Skip to content

Commit 5ef3fac

Browse files
author
“amith-skyflow”
committed
SK-2003: update readme
1 parent b98aab0 commit 5ef3fac

File tree

2 files changed

+236
-0
lines changed

2 files changed

+236
-0
lines changed

README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ The Skyflow Python SDK is designed to help with integrating Skyflow into a Pytho
3939
- [Generate bearer tokens with context](#generate-bearer-tokens-with-context)
4040
- [Generate scoped bearer tokens](#generate-scoped-bearer-tokens)
4141
- [Generate signed data tokens](#generate-signed-data-tokens)
42+
- [Bearer token expiry edge case](#bearer-token-expiry-edge-case)
4243
- [Logging](#logging)
4344
- [Reporting a Vulnerability](#reporting-a-vulnerability)
4445

@@ -2142,6 +2143,130 @@ Notes:
21422143
- The `time_to_live` (TTL) value should be specified in seconds.
21432144
- By default, the TTL value is set to 60 seconds.
21442145

2146+
#### Bearer token expiry edge case
2147+
When you use bearer tokens for authentication and API requests in SDKs, there's the potential for a token to expire after the token is verified as valid but before the actual API call is made, causing the request to fail unexpectedly due to the token's expiration. An error from this edge case would look something like this:
2148+
2149+
```txt
2150+
message: Authentication failed. Bearer token is expired. Use a valid bearer token. See https://docs.skyflow.com/api-authentication/
2151+
```
2152+
2153+
If you encounter this kind of error, retry the request. During the retry, the SDK detects that the previous bearer token has expired and generates a new one for the current and subsequent requests.
2154+
2155+
#### [Example](https://github.com/skyflowapi/skyflow-python/blob/v2/samples/service_account/bearer_token_expiry_example.py):
2156+
```python
2157+
import json
2158+
from skyflow.error import SkyflowError
2159+
from skyflow import Env
2160+
from skyflow import Skyflow, LogLevel
2161+
from skyflow.utils.enums import RedactionType
2162+
from skyflow.vault.tokens import DetokenizeRequest
2163+
2164+
"""
2165+
* This example demonstrates how to configure and use the Skyflow SDK
2166+
* to detokenize sensitive data stored in a Skyflow vault.
2167+
* It includes setting up credentials, configuring the vault, and
2168+
* making a detokenization request. The code also implements a retry
2169+
* mechanism to handle unauthorized access errors (HTTP 401).
2170+
"""
2171+
2172+
2173+
def detokenize_data(skyflow_client, vault_id):
2174+
try:
2175+
# Creating a list of tokens to be detokenized
2176+
detokenize_data = [
2177+
{
2178+
'token': '<TOKEN1>',
2179+
'redaction': RedactionType.REDACTED
2180+
},
2181+
{
2182+
'token': '<TOKEN2>',
2183+
'redaction': RedactionType.MASKED
2184+
}
2185+
]
2186+
2187+
# Building a detokenization request
2188+
detokenize_request = DetokenizeRequest(
2189+
data=detokenize_data,
2190+
continue_on_error=False
2191+
)
2192+
2193+
# Sending the detokenization request and receiving the response
2194+
response = skyflow_client.vault(vault_id).detokenize(detokenize_request)
2195+
2196+
# Printing the detokenized response
2197+
print('Detokenization successful:', response)
2198+
2199+
except SkyflowError as error:
2200+
print("Skyflow error occurred:", error)
2201+
raise
2202+
2203+
except Exception as error:
2204+
print("Unexpected error occurred:", error)
2205+
raise
2206+
2207+
2208+
def perform_detokenization():
2209+
try:
2210+
# Setting up credentials for accessing the Skyflow vault
2211+
cred = {
2212+
'clientID': '<YOUR_CLIENT_ID>',
2213+
'clientName': '<YOUR_CLIENT_NAME>',
2214+
'tokenURI': '<YOUR_TOKEN_URI>',
2215+
'keyID': '<YOUR_KEY_ID>',
2216+
'privateKey': '<YOUR_PRIVATE_KEY>',
2217+
}
2218+
2219+
skyflow_credentials = {
2220+
'credentials_string': json.dumps(cred) # Credentials string for authentication
2221+
}
2222+
2223+
credentials = {
2224+
'token': '<YOUR_TOKEN>'
2225+
}
2226+
2227+
# Configuring the Skyflow vault with necessary details
2228+
primary_vault_config = {
2229+
'vault_id': '<YOUR_VAULT_ID1>', # Vault ID
2230+
'cluster_id': '<YOUR_CLUSTER_ID1>', # Cluster ID
2231+
'env': Env.PROD, # Environment set to PROD
2232+
'credentials': credentials # Setting credentials
2233+
}
2234+
2235+
# Creating a Skyflow client instance with the configured vault
2236+
skyflow_client = (
2237+
Skyflow.builder()
2238+
.add_vault_config(primary_vault_config)
2239+
.add_skyflow_credentials(skyflow_credentials)
2240+
.set_log_level(LogLevel.ERROR) # Setting log level to ERROR
2241+
.build()
2242+
)
2243+
2244+
# Attempting to detokenize data using the Skyflow client
2245+
try:
2246+
detokenize_data(skyflow_client, primary_vault_config.get('vault_id'))
2247+
except SkyflowError as err:
2248+
# Retry detokenization if the error is due to unauthorized access (HTTP 401)
2249+
if err.http_code == 401:
2250+
print("Unauthorized access detected. Retrying...")
2251+
detokenize_data(skyflow_client, primary_vault_config.get('vault_id'))
2252+
else:
2253+
# Rethrow the exception for other error codes
2254+
raise err
2255+
2256+
except SkyflowError as error:
2257+
print('Skyflow Specific Error:', {
2258+
'code': error.http_code,
2259+
'message': error.message,
2260+
'details': error.details
2261+
})
2262+
except Exception as error:
2263+
print('Unexpected Error:', error)
2264+
2265+
2266+
# Invoke the function
2267+
perform_detokenization()
2268+
```
2269+
21452270
## Logging
21462271

21472272
The SDK provides logging using python's inbuilt `logging` library. By default the logging level of the SDK is set to `LogLevel.ERROR`. This can be changed by using `set_log_level(log_level)` as shown below:
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import json
2+
from skyflow.error import SkyflowError
3+
from skyflow import Env
4+
from skyflow import Skyflow, LogLevel
5+
from skyflow.utils.enums import RedactionType
6+
from skyflow.vault.tokens import DetokenizeRequest
7+
8+
"""
9+
* This example demonstrates how to configure and use the Skyflow SDK
10+
* to detokenize sensitive data stored in a Skyflow vault.
11+
* It includes setting up credentials, configuring the vault, and
12+
* making a detokenization request. The code also implements a retry
13+
* mechanism to handle unauthorized access errors (HTTP 401).
14+
"""
15+
16+
17+
def detokenize_data(skyflow_client, vault_id):
18+
try:
19+
# Creating a list of tokens to be detokenized
20+
detokenize_data = [
21+
{
22+
'token': '<TOKEN1>',
23+
'redaction': RedactionType.REDACTED
24+
},
25+
{
26+
'token': '<TOKEN2>',
27+
'redaction': RedactionType.MASKED
28+
}
29+
]
30+
31+
# Building a detokenization request
32+
detokenize_request = DetokenizeRequest(
33+
data=detokenize_data,
34+
continue_on_error=False
35+
)
36+
37+
# Sending the detokenization request and receiving the response
38+
response = skyflow_client.vault(vault_id).detokenize(detokenize_request)
39+
40+
# Printing the detokenized response
41+
print('Detokenization successful:', response)
42+
43+
except SkyflowError as error:
44+
print("Skyflow error occurred:", error)
45+
raise
46+
47+
except Exception as error:
48+
print("Unexpected error occurred:", error)
49+
raise
50+
51+
52+
def perform_detokenization():
53+
try:
54+
# Setting up credentials for accessing the Skyflow vault
55+
cred = {
56+
'clientID': '<YOUR_CLIENT_ID>',
57+
'clientName': '<YOUR_CLIENT_NAME>',
58+
'tokenURI': '<YOUR_TOKEN_URI>',
59+
'keyID': '<YOUR_KEY_ID>',
60+
'privateKey': '<YOUR_PRIVATE_KEY>',
61+
}
62+
63+
skyflow_credentials = {
64+
'credentials_string': json.dumps(cred) # Credentials string for authentication
65+
}
66+
67+
credentials = {
68+
'token': '<YOUR_TOKEN>'
69+
}
70+
71+
# Configuring the Skyflow vault with necessary details
72+
primary_vault_config = {
73+
'vault_id': '<YOUR_VAULT_ID1>', # Vault ID
74+
'cluster_id': '<YOUR_CLUSTER_ID1>', # Cluster ID
75+
'env': Env.PROD, # Environment set to PROD
76+
'credentials': credentials # Setting credentials
77+
}
78+
79+
# Creating a Skyflow client instance with the configured vault
80+
skyflow_client = (
81+
Skyflow.builder()
82+
.add_vault_config(primary_vault_config)
83+
.add_skyflow_credentials(skyflow_credentials)
84+
.set_log_level(LogLevel.ERROR) # Setting log level to ERROR
85+
.build()
86+
)
87+
88+
# Attempting to detokenize data using the Skyflow client
89+
try:
90+
detokenize_data(skyflow_client, primary_vault_config.get('vault_id'))
91+
except SkyflowError as err:
92+
# Retry detokenization if the error is due to unauthorized access (HTTP 401)
93+
if err.http_code == 401:
94+
print("Unauthorized access detected. Retrying...")
95+
detokenize_data(skyflow_client, primary_vault_config.get('vault_id'))
96+
else:
97+
# Rethrow the exception for other error codes
98+
raise err
99+
100+
except SkyflowError as error:
101+
print('Skyflow Specific Error:', {
102+
'code': error.http_code,
103+
'message': error.message,
104+
'details': error.details
105+
})
106+
except Exception as error:
107+
print('Unexpected Error:', error)
108+
109+
110+
# Invoke the function
111+
perform_detokenization()

0 commit comments

Comments
 (0)