|
1 | | -# Python SDK for Secure Native |
| 1 | +<p align="center"> |
| 2 | + <a href="https://www.securenative.com"><img src="https://user-images.githubusercontent.com/45174009/77826512-f023ed80-7120-11ea-80e0-58aacde0a84e.png" alt="SecureNative Logo"/></a> |
| 3 | +</p> |
2 | 4 |
|
3 | | -## How to get it? |
4 | | -the python SDK is published to PyPi so you can just use `pip` to install it: |
| 5 | +<p align="center"> |
| 6 | + <b>A Cloud-Native Security Monitoring and Protection for Modern Applications</b> |
| 7 | +</p> |
| 8 | +<p align="center"> |
| 9 | + <a href="https://github.com/securenative/securenative-python"> |
| 10 | + <img alt="Github Actions" src="https://github.com/securenative/securenative-java/workflows/CI/badge.svg"> |
| 11 | + </a> |
| 12 | +</p> |
| 13 | +<p align="center"> |
| 14 | + <a href="https://docs.securenative.com">Documentation</a> | |
| 15 | + <a href="https://docs.securenative.com/quick-start">Quick Start</a> | |
| 16 | + <a href="https://blog.securenative.com">Blog</a> | |
| 17 | + <a href="">Chat with us on Slack!</a> |
| 18 | +</p> |
| 19 | +<hr/> |
| 20 | + |
| 21 | + |
| 22 | +[SecureNative](https://www.securenative.com/) performs user monitoring by analyzing user interactions with your application and various factors such as network, devices, locations and access patterns to stop and prevent account takeover attacks. |
| 23 | + |
| 24 | + |
| 25 | +## Install the SDK |
| 26 | + |
| 27 | +When using PyPi, run the following: |
5 | 28 | ```bash |
6 | 29 | pip install securenative |
7 | 30 | ``` |
8 | 31 |
|
9 | 32 | ## Initialize the SDK |
10 | | -Go to the settings page of your SecureNative account and find your API key, afterwards add this line on your application main module. |
| 33 | + |
| 34 | +To get your *API KEY*, login to your SecureNative account and go to project settings page: |
| 35 | + |
| 36 | +### Option 1: Initialize via Config file |
| 37 | +SecureNative can automatically load your config from *securenative.ini* file or from the file that is specified in your *SECURENATIVE_CONFIG_FILE* env variable: |
| 38 | + |
11 | 39 | ```python |
12 | | -import securenative |
| 40 | +from securenative.securenative import SecureNative |
13 | 41 |
|
14 | | -# Many lines of code ... |
15 | 42 |
|
16 | | -if __name__=='__main__': |
17 | | - # Your bootstrap code |
18 | | - securenative.init('API_KEY') # Should be called before any other call to secure native |
| 43 | +secureative = SecureNative.init() |
19 | 44 | ``` |
| 45 | +### Option 2: Initialize via API Key |
20 | 46 |
|
21 | | -## Tracking Events (async) |
22 | | -Once the SDK has been initialized, you can start sending new events with the `track` function: |
23 | 47 | ```python |
24 | | -import securenative |
25 | | -from securenative.event_options import Event, User |
| 48 | +from securenative.securenative import SecureNative |
26 | 49 |
|
27 | | -def my_login_function(): |
28 | | - # Many lines of code ... |
29 | | - |
30 | | - event = Event( # Build the event from the request's context |
31 | | - event_type=securenative.event_types.login, |
32 | | - ip='35.199.23.1', |
33 | | - remote_ip='35.199.23.2', |
34 | | - user_agent='Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-URL-Manager Mobile Safari/537.36', |
35 | | - sn_cookie_value='eyJjaWQiOiJkYzgyYjdhZS00ODFkLTQyODItYTMyZC0xZTU1Njk2ZjNmZTQiLCJmcCI6Ijk5NGYzZjVjZTRiYWUwODQzMTRhOTFkNzgyN2I1MWYuMjQ3MDBmOWYxOTg2ODAwYWI0ZmNjODgwNTMwZGQwZWQifQ', |
36 | | - user=User( |
37 | | - user_id='1', |
38 | | - user_email='1@example.com', |
39 | | - user_name='example example' |
40 | | - ) |
41 | | - ) |
42 | | - |
43 | | - # Track it: |
44 | | - securenative.track(event) |
45 | | - |
46 | | - # Many lines of code ... |
47 | 50 |
|
| 51 | +securenative = SecureNative.init_with_api_key("YOUR_API_KEY") |
48 | 52 | ``` |
49 | 53 |
|
50 | | -## Verification Events (sync) |
51 | | -Once the SDK has been initialized, you can protect sensitive operation by calling the `verify` function, this function will return the risk analysis of the current user. |
| 54 | +### Option 3: Initialize via ConfigurationBuilder |
| 55 | +```python |
| 56 | +from securenative.securenative import SecureNative |
| 57 | + |
| 58 | + |
| 59 | +securenative = SecureNative.init_with_options(SecureNative.config_builder() |
| 60 | + .with_api_key("API_KEY") |
| 61 | + .with_max_events(10) |
| 62 | + .with_log_level("ERROR") |
| 63 | + .build()) |
| 64 | +``` |
52 | 65 |
|
| 66 | +## Getting SecureNative instance |
| 67 | +Once initialized, sdk will create a singleton instance which you can get: |
53 | 68 | ```python |
54 | | -import securenative |
55 | | -from securenative.event_options import Event, User |
| 69 | +from securenative.securenative import SecureNative |
| 70 | + |
| 71 | + |
| 72 | +secureNative = SecureNative.get_instance() |
| 73 | +``` |
| 74 | + |
| 75 | +## Tracking events |
| 76 | + |
| 77 | +Once the SDK has been initialized, tracking requests sent through the SDK |
| 78 | +instance. Make sure you build event with the EventBuilder: |
| 79 | + |
| 80 | + ```python |
| 81 | +from securenative.securenative import SecureNative |
| 82 | +from securenative.event_options_builder import EventOptionsBuilder |
| 83 | +from securenative.enums.event_types import EventTypes |
| 84 | +from securenative.models.user_traits import UserTraits |
| 85 | + |
56 | 86 |
|
57 | | -def my_change_password_function(): |
58 | | - # Many lines of code... |
| 87 | +securenative = SecureNative.get_instance() |
| 88 | + |
| 89 | +context = SecureNative.context_builder().\ |
| 90 | + with_ip("127.0.0.1").\ |
| 91 | + with_client_token("SECURED_CLIENT_TOKEN").\ |
| 92 | + with_headers({"user-agent", "Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405"}).\ |
| 93 | + build() |
| 94 | + |
| 95 | +event_options = EventOptionsBuilder(EventTypes.LOG_IN).\ |
| 96 | +with_user_id("USER_ID").\ |
| 97 | + with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")).\ |
| 98 | + with_context(context).\ |
| 99 | + with_properties({"prop1": "CUSTOM_PARAM_VALUE", "prop2": True, "prop3": 3}).\ |
| 100 | + build() |
| 101 | + |
| 102 | +securenative.track(event_options) |
| 103 | + ``` |
| 104 | + |
| 105 | +You can also create request context from requests: |
| 106 | + |
| 107 | +```python |
| 108 | +from securenative.securenative import SecureNative |
| 109 | +from securenative.event_options_builder import EventOptionsBuilder |
| 110 | +from securenative.enums.event_types import EventTypes |
| 111 | +from securenative.models.user_traits import UserTraits |
| 112 | + |
| 113 | + |
| 114 | +def track(request): |
| 115 | + securenative = SecureNative.get_instance() |
| 116 | + context = SecureNative.context_builder().from_http_request(request).build() |
| 117 | + |
| 118 | + event_options = EventOptionsBuilder(EventTypes.LOG_IN).\ |
| 119 | + with_user_id("USER_ID").\ |
| 120 | + with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")).\ |
| 121 | + with_context(context).\ |
| 122 | + with_properties({"prop1": "CUSTOM_PARAM_VALUE", "prop2": True, "prop3": 3}).\ |
| 123 | + build() |
59 | 124 |
|
60 | | - event = Event( # Build the event from the request's context |
61 | | - event_type=securenative.event_types.verify, |
62 | | - ip='35.199.23.1', |
63 | | - remote_ip='35.199.23.2', |
64 | | - user_agent='Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-URL-Manager Mobile Safari/537.36', |
65 | | - sn_cookie_value='eyJjaWQiOiJkYzgyYjdhZS00ODFkLTQyODItYTMyZC0xZTU1Njk2ZjNmZTQiLCJmcCI6Ijk5NGYzZjVjZTRiYWUwODQzMTRhOTFkNzgyN2I1MWYuMjQ3MDBmOWYxOTg2ODAwYWI0ZmNjODgwNTMwZGQwZWQifQ', |
66 | | - user=User( |
67 | | - user_id='1', |
68 | | - user_email='1@example.com', |
69 | | - user_name='example example' |
70 | | - ) |
71 | | - ) |
72 | | - |
73 | | - result = securenative.verify(event) |
74 | | - if result['riskLevel'] == 'high': |
75 | | - return 'Cannot change password' |
76 | | - elif result['riskLevel'] == 'medium': |
77 | | - return 'MFA' |
78 | | - |
79 | | - # Many lines of code... |
| 125 | + securenative.track(event_options) |
80 | 126 | ``` |
81 | 127 |
|
82 | | -## Verifying Incoming Webhooks |
83 | | -You can use the SDK to verify incoming webhooks from Secure Native, just call the `veriy_webhook` function which return a boolean which indicates if the webhook came from Secure Native servers. |
| 128 | +## Verify events |
| 129 | + |
| 130 | +**Example** |
| 131 | + |
84 | 132 | ```python |
85 | | -import securenative |
86 | | - |
87 | | -@post('/sn/webhook') |
88 | | -def sn_webhook_handler(headers, body): |
89 | | - sig_header = headers["X-SecureNative"] |
90 | | - if securenative.verify_webhook(sig_header, body): |
91 | | - # Handle the webhook |
92 | | - level = body['riskLevel'] |
93 | | - pass |
94 | | - else: |
95 | | - # This reqeust wasn't sent from Secure Native servers, you can dismiss/investigate it |
96 | | - pass |
| 133 | +from securenative.securenative import SecureNative |
| 134 | +from securenative.event_options_builder import EventOptionsBuilder |
| 135 | +from securenative.enums.event_types import EventTypes |
| 136 | +from securenative.models.user_traits import UserTraits |
| 137 | + |
| 138 | + |
| 139 | +def track(request): |
| 140 | + securenative = SecureNative.get_instance() |
| 141 | + context = SecureNative.context_builder().from_http_request(request).build() |
| 142 | + |
| 143 | + event_options = EventOptionsBuilder(EventTypes.LOG_IN).\ |
| 144 | + with_user_id("USER_ID").\ |
| 145 | + with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")).\ |
| 146 | + with_context(context).\ |
| 147 | + with_properties({"prop1": "CUSTOM_PARAM_VALUE", "prop2": True, "prop3": 3}).\ |
| 148 | + build() |
97 | 149 |
|
| 150 | + verify_result = securenative.verify(event_options) |
| 151 | + verify_result.risk_level # Low, Medium, High |
| 152 | + verify_result.score # Risk score: 0 -1 (0 - Very Low, 1 - Very High) |
| 153 | + verify_result.triggers # ["TOR", "New IP", "New City"] |
98 | 154 | ``` |
| 155 | + |
| 156 | +## Webhook signature verification |
| 157 | + |
| 158 | +Apply our filter to verify the request is from us, for example: |
| 159 | + |
| 160 | +```python |
| 161 | +from securenative.securenative import SecureNative |
| 162 | + |
| 163 | + |
| 164 | +def webhook_endpoint(request): |
| 165 | + securenative = SecureNative.get_instance() |
| 166 | + |
| 167 | + # Checks if request is verified |
| 168 | + is_verified = securenative.verify_request_payload(request) |
| 169 | + ``` |
0 commit comments