Skip to content

feat: Add support for Token Vault Privileged Access - #840

Merged
developerkunal merged 5 commits into
v1from
go-v1-privileged-worker-token-vault
Aug 13, 2026
Merged

feat: Add support for Token Vault Privileged Access #840
developerkunal merged 5 commits into
v1from
go-v1-privileged-worker-token-vault

Conversation

@KartikJha

Copy link
Copy Markdown

feat(client): add Token Vault privileged access support

🔧 Changes

Adds support for configuring a client as a Token Vault privileged worker, which allows it to request Token Vault tokens on behalf of other users. This is an Early Access feature and must be enabled for the tenant.

Types added

  • ClientTokenVaultPrivilegedAccess — the configuration object itself, with three fields:
    • Credentials *[]ClientCredentialID — credentials attached to the worker (max 2). Required whenever the object is being set, on both POST /clients and PATCH /clients/{id}. Sending an empty array detaches every credential and disables the worker.
    • IPAllowlist *[]string — permitted IPv4/IPv6 addresses or CIDR ranges the worker may request tokens from (max 10).
    • Grants *[]ClientTokenVaultPrivilegedGrant — pins the connections, and the scopes within them, the worker may request tokens for (max 5 grants, max 20 scopes in total).
  • ClientCredentialID — references a client credential. On PATCH /clients/{id} only ID is accepted, referencing a credential created beforehand via ClientManager.CreateCredential; on POST /clients the credential material is supplied instead through CredentialType and PEM.
  • ClientTokenVaultPrivilegedGrant — a Connection name plus the Scopes allowed on it.

Fields added

  • Client.TokenVaultPrivilegedAccess *ClientTokenVaultPrivilegedAccess (token_vault_privileged_access).

Why the sub-fields are pointers to slices

Each sub-field is a *[]T so all three write semantics of the Management API can be expressed distinctly:

Value Sent as Effect
nil key omitted stored value left unchanged
&[]T{} [] stored value cleared
&[]T{...} [...] stored value replaced

Removing the whole object is a fourth case that requires a literal null for token_vault_privileged_access, which omitempty on a nil Client field cannot emit. That case is documented on the field and needs a custom PATCH request:

type clientPatch struct {
	TokenVaultPrivilegedAccess *ClientTokenVaultPrivilegedAccess `json:"token_vault_privileged_access"` // no omitempty
}

err := api.Request(ctx, http.MethodPatch, api.URI("clients", clientID), &clientPatch{})

CleanForPatch behaviour

Client.CleanForPatch now reduces a read-back credential list to bare IDs, since PATCH /clients/{id} only accepts credential references. Entries without an ID are deliberately left untouched rather than dropped — dropping them would silently detach the worker's credentials, whereas passing them through surfaces the API error. Credential material supplied for a create (CredentialType/PEM) is therefore preserved as-is, and an empty credentials list stays empty.

Usage

credential, err := api.Client.CreateCredential(ctx, clientID, &Credential{
	Name:           auth0.String("Worker Key"),
	CredentialType: auth0.String("public_key"),
	PEM:            auth0.String(publicKeyPEM),
})

err = api.Client.Update(ctx, clientID, &management.Client{
	TokenVaultPrivilegedAccess: &management.ClientTokenVaultPrivilegedAccess{
		Credentials: &[]management.ClientCredentialID{{ID: credential.ID}},
		IPAllowlist: &[]string{"10.0.0.1", "192.168.1.0/24"},
		Grants: &[]management.ClientTokenVaultPrivilegedGrant{
			{
				Connection: auth0.String("google-oauth2"),
				Scopes:     &[]string{"https://www.googleapis.com/auth/calendar.readonly"},
			},
		},
	},
})

Generated code

Regenerated getters and generated tests in management.gen.go / management.gen_test.go for the new types and field.

📚 References

Auth0 Management API: token_vault_privileged_access on POST /api/v2/clients and PATCH /api/v2/clients/{id} (Early Access).

🔬 Testing

  • TestClientTokenVaultPrivilegedAccess_MarshalJSON — unit tests over the (un)marshalling contract: nil sub-fields omitted, empty arrays emitted, populated arrays emitted, the create-time credential material shape, and unmarshalling a stored object.
  • TestClientTokenVaultPrivilegedAccess_CleanForPatch — unit tests that read-back credentials are reduced to IDs, credential material is preserved, and an empty credentials list survives.
  • TestClient_TokenVaultPrivilegedAccess — HTTP-recorded end-to-end test (test/data/recordings/TestClient_TokenVaultPrivilegedAccess.yaml) that creates a non-interactive client, creates a credential, attaches the object via PATCH, then asserts each write semantic in turn: an unrelated field update does not clobber the stored object, a populated array replaces while a nil sub-field is omitted, an empty array clears, and a custom PATCH with a literal null removes the object entirely.

Run against a tenant with the feature enabled:

make test-integration FILTER="TestClient_TokenVaultPrivilegedAccess"

Reviewers can replay the recordings without a tenant:

go test ./management/... -run 'TestClient.*TokenVaultPrivilegedAccess'

Not covered: server-side validation of the documented limits (2 credentials, 10 allowlist entries, 5 grants / 20 scopes) and the non-empty / no-duplicate scope rules — these are enforced by the API, not the SDK. The POST /clients path that inlines credential material is exercised only at the marshalling level, since the integration test must create credentials after the client exists in order to reference them.

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@KartikJha
KartikJha requested a review from a team as a code owner July 30, 2026 14:37
@KartikJha
KartikJha marked this pull request as draft July 30, 2026 14:38
@codecov-commenter

codecov-commenter commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.88%. Comparing base (b378ca5) to head (7c54bb7).
⚠️ Report is 1 commits behind head on v1.

Additional details and impacted files
@@            Coverage Diff             @@
##               v1     #840      +/-   ##
==========================================
+ Coverage   96.87%   96.88%   +0.01%     
==========================================
  Files          62       62              
  Lines       11261    11299      +38     
==========================================
+ Hits        10909    10947      +38     
  Misses        234      234              
  Partials      118      118              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@KartikJha
KartikJha force-pushed the go-v1-privileged-worker-token-vault branch from b94cf50 to d5f2862 Compare August 3, 2026 13:44
@KartikJha
KartikJha marked this pull request as ready for review August 3, 2026 13:44
@duedares-rvj duedares-rvj changed the title feat: tvpa initial commit feat: Add support for Token Vault Privileged Access Aug 12, 2026
Comment thread management/client.go

@developerkunal developerkunal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@developerkunal
developerkunal enabled auto-merge (squash) August 13, 2026 14:12
@developerkunal
developerkunal merged commit 2e4a6ac into v1 Aug 13, 2026
4 checks passed
@developerkunal
developerkunal deleted the go-v1-privileged-worker-token-vault branch August 13, 2026 14:16
@developerkunal developerkunal mentioned this pull request Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants