SK-3039:Fix missing roles & ctx in bearerToken. - #272
Merged
yaswanth-pula-skyflow merged 7 commits intoAug 4, 2026
Conversation
yaswanth-pula-skyflow
requested review from
Devesh-Skyflow,
Copilot,
saileshwar-skyflow and
skyflow-bharti
August 3, 2026 10:20
There was a problem hiding this comment.
Pull request overview
This PR fixes propagation and validation of credentials.roles and credentials.context so they reliably reach the service-account bearer token generation (including refresh), and expands credentials.context to accept dict/JSON objects with key validation.
Changes:
- Update
VaultClient.get_bearer_token()to build token-engine options from the resolvedcredentialsdict (not top-level config) and omit unset options. - Update credential validation to (a) reject
roles: [], (b) acceptcontextasstrordict, and (c) validate dict context keys early. - Add/adjust unit and end-to-end tests covering roles/context forwarding and the new validation behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/vault/client/test__client.py | Adds coverage for roles/context forwarding into token generation options (including refresh) and verifies top-level config keys are ignored. |
| tests/utils/validations/test__validations.py | Adds validation coverage for dict context, invalid keys/types, and the updated roles empty/type error behavior. |
| tests/client/test_skyflow.py | Adds end-to-end tests ensuring builder-configured roles/context reach the token engine. |
| skyflow/vault/client/client.py | Changes bearer-token option construction to read from credentials and omit unset values. |
| skyflow/utils/validations/_validations.py | Updates validation for roles empty list, and allows dict context with key validation via the token-engine helper. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
saileshwar-skyflow
approved these changes
Aug 3, 2026
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
tests/client/test_skyflow.py:461
- Same issue as above:
@patch("skyflow.vault.client.client.Skyflow")targets a non-existent symbol and will raise at test import/runtime. Remove it and update the test signature accordingly.
@patch("skyflow.vault.client.client.Skyflow")
@patch("skyflow.vault.client.client.generate_bearer_token_from_creds", return_value=("token", "bearer"))
def test_dict_context_reaches_token_engine(self, mock_gen, _mock_api):
skyflow/utils/validations/_validations.py:533
- The
request.tokenstype validation only runs whenrequest.tokensis truthy. This means invalid-but-falsy values (e.g.{}) bypass validation and can still flow into insert body building, potentially causing subtle behavior differences. If the intent is to validate whenever the caller providestokens, gate onis not Noneinstead of truthiness, and avoid the redundantor not request.tokenscheck (it can never be true insideif request.tokens:).
if request.tokens:
if not isinstance(request.tokens, list) or not request.tokens or not all(
isinstance(t, dict) for t in request.tokens):
log_error_log(SkyflowMessages.ErrorLogs.EMPTY_TOKENS.value.format(RequestOperation.INSERT), logger=logger)
raise SkyflowError(SkyflowMessages.Error.INVALID_TYPE_OF_DATA_IN_INSERT.value, invalid_input_error_code)
skyflow/utils/validations/_validations.py:573
validate_delete_requestchecks emptiness before validating type. For non-list falsy values (e.g.ids=""orids=()), this raisesEMPTY_RECORD_IDS_IN_DELETEinstead of the intendedINVALID_IDS_TYPE. To make the new type-safety guarantee consistent, validateidstype first (keeping a dedicatedNonecheck), then validate emptiness for lists.
if not request.ids:
log_error_log(SkyflowMessages.ErrorLogs.EMPTY_IDS.value.format(RequestOperation.DELETE), logger=logger)
raise SkyflowError(SkyflowMessages.Error.EMPTY_RECORD_IDS_IN_DELETE.value, invalid_input_error_code)
if not isinstance(request.ids, list):
Devesh-Skyflow
approved these changes
Aug 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SK-3039: Fix missing
roles/ctxin bearer tokens and harden request/config input validationProblem
rolesandcontextset undercredentialsinadd_vault_config()never reached the generated bearer token.VaultClient.get_bearer_token()readroles/ctxfrom the top-level config, but both are only accepted nested undercredentials— top-level keys are rejected byvalidate_keys, so the lookup always resolved toNone: no error, just a token with noctxclaim and norole:scope, on first generation and every auto-refresh.contextwas validated asstronly, rejecting a dict/JSON object atbuild()even though the token-generation engine already supports it.SkyflowError: dicttokenson insert, bare-string items in detokenizedata, non-string elements inroles, non-listidson delete, and non-stringskyflow_id/table/column_name/file_nameon update and file-upload.validate_update_connection_configdroppedconnection_idfromvalidate_credentials, so credential errors on the update path lost config context that the add path already included.Changes
Bearer token
roles/ctxVaultClient.get_bearer_token()now builds token options from the resolvedcredentialsdict instead of the top-level config, and calls the sharedvalidate_token_optionsdirectly — so a directly-constructedVaultClientcan no longer skip roles/context validation. Keys are omitted when unset rather than passed asNone.pathandcredentials_string, config-level and common credentials, and connection configs.credentials.contextnow accepts astror adict. Dict keys are validated at config time (^[a-zA-Z0-9_]+$), so an invalid key fails atbuild()instead of on the first API call. Empty dict is rejected as an empty context, matching existing empty-string behaviour.empty/invaliderror messages forroles: a non-list now reports "Specify roles as an array" instead of "Specify at least one role".roles: []now raisesEMPTY_ROLESinstead of silently producing an unscoped token. Each element ofrolesmust now be a non-empty string, or validation raises — previously a non-string role was silently stringified into the OAuth scope.validate_update_connection_confignow passesconnection_idthrough tovalidate_credentials, so its error messages include the connection id like the add path already does.Insert / detokenize type safety
InsertRequest(tokens=...)with a non-list/non-dict-of-dicts value now raisesINVALID_TYPE_OF_DATA_IN_INSERTinstead of crashing in the diagnostic logging loop.DetokenizeRequest(data=...)with bare strings now always raisesINVALID_TOKENS_LIST_VALUE, instead of only crashing when a string happened to contain"token"as a substring.Delete / update / file-upload validation
DeleteRequest(ids=...)with a non-list value now raisesINVALID_IDS_TYPE.UpdateRequestandFileUploadRequestnow type-checkskyflow_id(newINVALID_SKYFLOW_ID_TYPEmessage), andFileUploadRequesttype-checkstable,column_name, andfile_name, raising the existing corresponding error instead of crashing on.strip().Behaviour change
roles: []and non-stringroleselements previously passed validation and produced an unscoped or corrupted token; both now raise. Everything else is either a crash fix or a message correction — the accept/reject boundary for already-valid input is unchanged.rolesandcontextremain optional; validation only runs when the key is present.Tests
tests/vault/client/test__client.py: string and dict context plus roles forwarded on the path and credentials-string flows; options omitted when unset; top-level config keys explicitly ignored;token_uricoexistence; refresh path verified directly and end-to-end throughinitialize_client_configuration().tests/utils/validations/test__validations.py: string/dict context accepted, empty dict, invalid ctx key, invalid types, config-scoped message variant, end-to-endvalidate_vault_config, the threerolescases plus non-string role elements, dicttokenson insert, bare-string detokenizedata, non-list deleteids, non-stringskyflow_id/table/column_name/file_nameon update and file-upload, andconnection_idincluded invalidate_update_connection_configerror messages.tests/client/test_skyflow.py: end-to-endbuilder().add_vault_config(...).build()asserting the options handed to the token engine.roles/ctxfrom the client test fixture — that shape is rejected by real validation.