You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add JSON object support for ctx field in bearer token and signed data token generation
Extend the Python SDK's bearer token and signed data token generation to
accept a dict for the ctx field, in addition to the existing string type.
This enables structured context for conditional data access policies where
ctx object keys map to Skyflow CEL policy variables (e.g.,
request.context.role, request.context.department).
Changes:
- _utils.py: add _validate_and_resolve_ctx() function with key validation
(^[a-zA-Z0-9_]+$), update get_signed_jwt() and get_signed_tokens() to
validate and conditionally include ctx in JWT claims
- _skyflow_messages.py: add INVALID_CTX_TYPE and INVALID_CTX_MAP_KEY errors
- Tests: add 14+ validation test cases for dict ctx, invalid keys, invalid
types, empty dict, nested objects, mixed value types
- Samples: add JSON object context examples for both bearer and signed tokens
- README: document both string and dict ctx patterns with CEL policy
variable mapping
Technical note: PyJWT's jwt.encode() already handles both types — a string
serializes as a JSON string, a dict serializes as a JSON object in the JWT
payload. The main addition is proper validation and error handling.
Resolves: SK-2681, DOCU-1440
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+51-4Lines changed: 51 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -703,18 +703,65 @@ options = {
703
703
704
704
Embed context values into a bearer token during generation so you can reference those values in your policies. This enables more flexible access controls, such as tracking end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization.
705
705
706
-
Generate bearer tokens containing context information using a service account with the context_id identifier. Context information is represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a context_identifier claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions.
706
+
Generate bearer tokens containing context information using a service account with the `context_id` identifier. Context information is represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a `context_identifier` claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions.
707
+
708
+
The `ctx` parameter accepts either a **string** or a **dict**:
709
+
710
+
**String context** — use when your policy references a single context value:
**Dict context** — use when your policy needs multiple context values for conditional data access. Each key in the dict maps to a Skyflow CEL policy variable under `request.context.*`:
With the dict above, your Skyflow policies can reference `request.context.role`, `request.context.department`, and `request.context.user_id` to make conditional access decisions.
731
+
732
+
Dict keys must contain only alphanumeric characters and underscores (`[a-zA-Z0-9_]`). Invalid keys will raise a `SkyflowError`.
707
733
708
734
> [!TIP]
709
-
> See the full example in the samples directory: [token_generation_with_context_example.py](samples/service_account/token_generation_with_context_example.py)
710
-
> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow.
735
+
> See the full example in the samples directory: [token_generation_with_context_example.py](samples/service_account/token_generation_with_context_example.py)
736
+
> See Skyflow's [context-aware authorization](https://docs.skyflow.com) and [conditional data access](https://docs.skyflow.com)docs for policy variable syntax like `request.context.*`.
711
737
712
738
#### Generate signed data tokens: `generate_signed_data_tokens(filepath, options)`
713
739
714
740
Digitally sign data tokens with a service account's private key to add an extra layer of protection. Skyflow generates data tokens when sensitive data is inserted into the vault. Detokenize signed tokens only by providing the signed data token along with a bearer token generated from the service account's credentials. The service account must have the necessary permissions and context to successfully detokenize the signed data tokens.
715
741
742
+
The `ctx` parameter on signed data tokens also accepts either a **string** or a **dict**, using the same format as bearer tokens:
743
+
744
+
```python
745
+
# String context
746
+
options = {
747
+
'ctx': 'user_12345',
748
+
'data_tokens': ['dataToken1', 'dataToken2'],
749
+
'time_to_live': 90,
750
+
}
751
+
752
+
# Dict context
753
+
options = {
754
+
'ctx': {
755
+
'role': 'analyst',
756
+
'department': 'research',
757
+
},
758
+
'data_tokens': ['dataToken1', 'dataToken2'],
759
+
'time_to_live': 90,
760
+
}
761
+
```
762
+
716
763
> [!TIP]
717
-
> See the full example in the samples directory: [signed_token_generation_example.py](samples/service_account/signed_token_generation_example.py)
764
+
> See the full example in the samples directory: [signed_token_generation_example.py](samples/service_account/signed_token_generation_example.py)
718
765
> See [docs.skyflow.com](https://docs.skyflow.com) for more details on authentication, access control, and governance for Skyflow.
Copy file name to clipboardExpand all lines: skyflow/utils/_skyflow_messages.py
+2Lines changed: 2 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -60,6 +60,8 @@ class Error(Enum):
60
60
EMPTY_CONTEXT=f"{error_prefix} Initialization failed. Invalid context provided. Specify context as type Context."
61
61
INVALID_CONTEXT_IN_CONFIG=f"{error_prefix} Initialization failed. Invalid context for {{}} with id {{}}. Specify a valid context."
62
62
INVALID_CONTEXT=f"{error_prefix} Initialization failed. Invalid context. Specify a valid context."
63
+
INVALID_CTX_TYPE=f"{error_prefix} Initialization failed. Invalid ctx type. Specify ctx as a string or a dict."
64
+
INVALID_CTX_MAP_KEY=f"{error_prefix} Initialization failed. Invalid key '{{}}' in ctx dict. Keys must contain only alphanumeric characters and underscores."
0 commit comments