Vault
Shark Token Vault — broker third-party OAuth credentials (Google, Microsoft, Slack, Linear, Jira, custom) without your agents ever seeing the refresh tokens.
The vault stores encrypted refresh tokens server-side. Agents authenticate with their own DPoP-bound Shark token and ask the vault for a fresh access token for a connection they've been authorized to use. The third-party access token is never persisted on the agent.
Mental model
[user signed in with Shark] ── connects "google_gmail" via OAuth ──▶ [vault stores refresh_token]
│
[agent with DPoP-bound Shark token, scope vault:read] ───────────▶ [vault decrypts + refreshes if needed]
│
▼
returns fresh access_token to agent
Out of scope today: provider/template CRUD (P1 backlog), enroll-from-code helper. Connections are created via the dashboard's OAuth flow or the lower-level vault HTTP routes.
Construct
List connections (admin)
VaultConnectionRecord carries id, user_id, provider_id, provider_name, created_at, updated_at, needs_reauth.
Fetch a fresh token (agent path)
The agent must have a DPoP-bound Shark access token with vault:read scope. The vault validates the DPoP proof, the scope, and the tok.UserID binding before decrypting.
The Python signature is the canonical one. The TypeScript SDK's fetchToken(referenceToken) currently uses an older shape — close-but-not-identical. Track the parity gap in sdk/HANDOFF.md.
| Param | Notes |
|---|---|
provider | Provider slug (e.g. google_gmail, slack) |
bearer_token | Agent's DPoP-bound Shark access token |
prover | The keypair whose JWK matches token's cnf.jkt |
Returns VaultTokenResult with access_token, token_type, expires_at, provider.
Disconnect a connection
Optionally cascade-revokes tokens for every agent that has touched the connection (Layer 5 of the five-layer revocation model).
Pass cascade_to_agents=False to silently disconnect without revoking agent tokens.
Common providers
| Provider slug | Notes |
|---|---|
google_gmail | Read/send Gmail |
google_calendar | Calendar API |
google_drive | Drive API |
microsoft | M365 unified |
slack | Slack workspace |
linear | Linear API |
jira | Atlassian Jira |
notion | Notion API |
For a custom OAuth provider, the dashboard can register a template — but the SDK does not yet expose programmatic CRUD for provider templates (P1 backlog).
Errors
VaultError(message, status_code):
401— invalid or expired DPoP token403— missingvault:readscope on the agent token404— no connection for that provider/user
See also
- Delegation and agents — vault is Layer 5 of revocation
- Cookbook: agent acts on Gmail — end-to-end recipe