Vaults
Store credentials, authorize Session access, and manage rotation and expiry.
On this page
Choose a credential typeAuthentication and endpointsService-origin MCP credentialsOAuth credentialsDelegate a secret to a Sandbox1. Store the credential2. Bind the credential to a Session3. Run work using the credentialRotate a credentialDelete, expire, and list credentialsErrors and recoverySDK and protocol compatibilityA Vault stores organization-scoped credentials. Your application obtains permission from the external service, stores a credential, and chooses which Sessions may use it. Rebyte stores the secret encrypted and returns only public metadata.
Available from October 12, 2026:
sandbox_environmentandenvironment.vault_credentialsextend Rebyte Vaults with explicit Sandbox delegation. These are Rebyte-specific fields; SDK type support is described below. Existing MCP credential behavior is unchanged.
Choose a credential type
auth.type | Use | Where the secret is available |
|---|---|---|
static_bearer | A bearer token for service-origin HTTP MCP. | Rebyte's service sends it to the configured MCP server. It is not injected into the Sandbox. |
mcp_oauth | An OAuth access token for service-origin HTTP MCP, with optional refresh configuration. | Rebyte's service uses and, when configured, refreshes it. It is not injected into the Sandbox. |
sandbox_environment | A named environment variable for commands and selected stdio MCP processes in a Session Sandbox. | The process receives the actual secret. Sandbox code and the Agent can read it. |
These are provider-independent capabilities. Your application owns end-user
authorization, provider login, token issuance, and any mapping from jobs or issues
to Sessions. For sandbox_environment, your application also owns token renewal.
Rebyte checks the stored expiry; it does not contact the provider to refresh this
credential type. No issue tracker, repository, Runner, or ACP configuration is
required by Vaults.
Already connected an account in Rebyte? Add a Platform connection to the API Agent to reuse supported platform-managed authentication. A Vault does not automatically import those accounts.
Authentication and endpoints
Keep your Rebyte organization API key on your application server. Your server must authorize each end user before creating or using their credentials. Vaults are scoped to the organization; they do not provide a separate end-user access policy.
All paths below are relative to the API base URL, normally
https://api.rebyte.ai/v1. Send Authorization: Bearer REBYTE_API_KEY and
OpenAI-Beta: agents=v1; JSON requests also use Content-Type: application/json.
Although the SDK namespace is client.beta.agents.vaults, the HTTP collection is
/v1/vaults.
| Operation | Method and path | Required scope |
|---|---|---|
| Create a Vault | POST /vaults | api.vaults.write |
| List Vaults | GET /vaults | api.vaults.read |
| Retrieve a Vault | GET /vaults/{vault_id} | api.vaults.read |
| Delete a Vault | DELETE /vaults/{vault_id} | api.vaults.write |
| Create a credential | POST /vaults/{vault_id}/credentials | api.vaults.write |
| List credentials | GET /vaults/{vault_id}/credentials | api.vaults.read |
| Retrieve a credential | GET /vaults/{vault_id}/credentials/{credential_id} | api.vaults.read |
| Rotate a credential | POST /vaults/{vault_id}/credentials/{credential_id} | api.vaults.write |
| Delete a credential | DELETE /vaults/{vault_id}/credentials/{credential_id} | api.vaults.write |
Creation returns HTTP 201; the other successful operations return HTTP 200.
Session creation uses POST /agents/sessions and requires tasks:write; reading
Sessions and Turns requires tasks:read. Vault scopes govern Vault CRUD, not
Session execution. Existing API keys are not automatically granted Vault scopes.
A Vault creation body accepts optional name and metadata. Credential creation
requires name and auth. Names are trimmed, nonempty when supplied, and limited
to 256 UTF-8 bytes. Secret strings are nonempty and limited to 65,536 characters.
Vault metadata accepts up to 16 string entries, with keys up to 64 characters
and values up to 512 characters. Do not put secrets in names or metadata.
Service-origin MCP credentials
Use the client from Quickstart. With mcpUrl and
a provider-issued accessToken supplied by your application:
const vault = await client.beta.agents.vaults.create({ name: 'User authorization' });
await client.beta.agents.vaults.credentials.create(vault.id, {
name: 'Company MCP',
auth: {
type: 'static_bearer',
mcp_server_url: mcpUrl,
token: accessToken,
},
});
const session = await client.beta.agents.sessions.create({
agent_id: agent.id,
vault_ids: [vault.id],
environment: { type: 'openai_hosted' },
});
This assumes the saved Agent has a matching service-origin HTTP MCP tool. A
Sandbox is optional for this MCP use case. mcp_server_url must be HTTPS without
embedded credentials or a fragment. Credential selection matches the exact MCP
server URL. If several credentials match, select an explicit credential_id in
the Session's MCP tool configuration. The chosen identity remains attached to the
Session; deletion does not silently select another identity. See MCP connections.
OAuth credentials
Use this auth object when creating an OAuth credential. The variables come from
your application's provider authorization flow:
const auth = {
type: 'mcp_oauth',
mcp_server_url: mcpUrl,
access_token: accessToken,
expires_at: tokenExpiresAt,
refresh: {
client_id: oauthClientId,
refresh_token: refreshToken,
token_endpoint: tokenEndpoint,
token_endpoint_auth: {
type: 'client_secret_basic',
client_secret: oauthClientSecret,
},
},
};
expires_at is an ISO 8601 timestamp with a timezone, or null; omission means
no stored expiry. refresh is optional or null. When present, its four fields
shown above are required. token_endpoint must be HTTPS without embedded
credentials or a fragment. Client authentication accepts { type: 'none' },
or client_secret_basic / client_secret_post with a client_secret.
Optional refresh.scope and refresh.resource are sent during refresh.
Rebyte supports provider-rotated refresh tokens and serializes refresh with
manual credential rotation. Your application owns the initial login and consent.
Delegate a secret to a Sandbox
Rebyte extension. This flow uses a generic SERVICE_TOKEN.
It applies to any provider whose credential can be used by a Sandbox process.
The official openai@7.15.0 client does not declare these extension fields in its
types. The following JavaScript uses its ordinary Vault and Session methods.
For TypeScript, use the client's generic HTTP post method with the paths above
and the OpenAI-Beta header; do not treat this as an upstream typed credential.
Rebyte's reusable SDK types have not yet been updated for this extension.
1. Store the credential
Install openai@7.15.0 with pnpm and set REBYTE_API_KEY to an
organization key with the Vault and Session scopes needed above. Your application
supplies SERVICE_TOKEN and SERVICE_TOKEN_EXPIRES_AT from the provider; the
expiry must be a future ISO 8601 timestamp. Save the three numbered examples
together as a server-side .mjs script:
import OpenAI from 'openai';
for (const name of ['REBYTE_API_KEY', 'SERVICE_TOKEN', 'SERVICE_TOKEN_EXPIRES_AT']) {
if (!process.env[name]) throw new Error(`Set ${name}`);
}
const expiresAt = process.env.SERVICE_TOKEN_EXPIRES_AT;
if (!Number.isFinite(Date.parse(expiresAt)) || Date.parse(expiresAt) <= Date.now()) {
throw new Error('SERVICE_TOKEN_EXPIRES_AT must be a future timestamp');
}
const client = new OpenAI({
apiKey: process.env.REBYTE_API_KEY,
baseURL: 'https://api.rebyte.ai/v1',
maxRetries: 0,
});
const vault = await client.beta.agents.vaults.create({ name: 'Application access' });
const credential = await client.beta.agents.vaults.credentials.create(vault.id, {
name: 'Service access',
auth: {
type: 'sandbox_environment',
secret_name: 'SERVICE_TOKEN',
secret_value: process.env.SERVICE_TOKEN,
expires_at: expiresAt,
},
});
| Field | Contract |
|---|---|
auth.type | Required: sandbox_environment. |
auth.secret_name | Required. Matches [A-Za-z_][A-Za-z0-9_]{0,127}; up to 128 characters. Fixed for this credential's lifetime. |
auth.secret_value | Required, write-only secret string. Never returned by the credential API. |
auth.expires_at | Optional ISO 8601 timestamp with a timezone, or null. Omitted/null means no stored expiry. An already expired credential can be stored but cannot be bound or used. |
The public credential contains id, object: 'vault.credential', vault_id,
name, created_at, updated_at, and auth. For this type, public auth
contains only type, secret_name, and expires_at.
2. Bind the credential to a Session
const session = await client.beta.agents.sessions.create({
agent: {
model: 'gpt-6-luna',
instructions: 'Never print or copy credential values into output or files.',
},
vault_ids: [vault.id],
environment: {
type: 'openai_hosted',
vault_credentials: [{ vault_id: vault.id, credential_id: credential.id }],
setup_commands: [{ command: 'test -n "$SERVICE_TOKEN"', cwd: '/workspace' }],
network: { access: 'disabled' },
},
});
console.log({ vaultId: vault.id, credentialId: credential.id, sessionId: session.id });
vault_ids makes Vaults available to the Session; environment.vault_credentials
selects the exact Sandbox credentials. Attaching a Vault alone injects none of
its secrets. Each binding requires both IDs, and its Vault must also appear in
vault_ids. All resources must belong to the Session's organization.
vault_credentials is optional and accepts 1–32 bindings when present; omit it
when none are needed. It is supported only with environment.type: 'openai_hosted'.
Credential variable names must be unique across bindings and must not overlap
environment.env. Bindings are fixed when Environment configuration is created.
To select different credentials, create a new Environment (inline in a new Session
or standalone with explicit sharing); to change a selected secret's value, rotate
the same credential.
Available on the Rebyte API: shared Environments
retain their original Vault selection. A referencing Session cannot override it
with its own vault_ids, and Sandbox-visible values are available to code from
all attached Sessions. Service-origin MCP credential selection remains Session-owned.
Rebyte validates references at Session creation and again when resolving credentials for new execution. Public Session metadata includes the bindings; stored environment configuration holds references, not a snapshot of the secret. Creating a Session does not eagerly start its Sandbox or run setup commands.
3. Run work using the credential
Send input using the Session events API. For a check that does not print the value:
await client.beta.agents.sessions.events.create(session.id, {
'Idempotency-Key': `credential-check-${session.id}`,
events: [{
type: 'agent.session.input.message',
input: [{ role: 'user', content: [{
type: 'input_text',
text: 'Run test -n "$SERVICE_TOKEN" in the Sandbox. Report only whether it succeeded.',
}] }],
}],
});
This acknowledges the input; inspect the Turn for completion. Subscribe to live events before submitting if you need live output. The network-disabled example checks delivery only. To call an external service, configure the Sandbox's network policy for its domain.
Delegated variables are supplied to package installation, setup commands,
exec_command, and direct code execution. Stdio MCP servers can select a variable
through transport.env_vars: ['SERVICE_TOKEN']; they do not automatically receive
every binding. This does not add bearer-header substitution to environment-origin
HTTP MCP. Configure HTTP MCP authentication through its own supported fields.
Rebyte does not insert secret values into model instructions or public resources as part of injection. The Agent and Sandbox code can still read and disclose them, including through tool output or files. An instruction to avoid disclosure is not an access boundary. Delegate only the provider permissions the task needs.
Rotate a credential
Rotation uses POST /vaults/{vault_id}/credentials/{credential_id} with an auth
object. The credential ID and auth type remain unchanged. MCP server URLs and
Sandbox variable names cannot be changed by rotation.
| Type | Rotation body inside auth |
|---|---|
static_bearer | type and a new token. |
mcp_oauth | type and optional access_token, expires_at, and refresh updates. |
sandbox_environment | type, new secret_value, and an explicit expires_at timestamp or null. Omission of expiry is rejected. |
For a Sandbox credential, obtain renewedToken and renewedExpiresAt from your
provider, then update the credential already bound to the Session:
await client.beta.agents.vaults.credentials.update(credential.id, {
vault_id: vault.id,
auth: {
type: 'sandbox_environment',
secret_value: renewedToken,
expires_at: renewedExpiresAt,
},
});
New process launches resolve the new value without creating another Session. Existing processes, interactive command sessions, and already-started stdio MCP servers retain their original environment. Rotation is not a process restart.
For MCP OAuth rotation, a supplied new access_token without expires_at clears
the stored expiry. refresh: null removes refresh configuration. An existing
refresh configuration can update its token, scope, or client secret; rotation
cannot add a missing refresh configuration or change its client-authentication
type, client ID, resource, or token endpoint.
Delete, expire, and list credentials
await client.beta.agents.vaults.credentials.delete(credential.id, { vault_id: vault.id });
// To archive the entire Vault and erase every credential it holds:
await client.beta.agents.vaults.delete(vault.id);
Deletion archives the resource and erases stored secrets. Public metadata remains
retrievable. Repeated deletion is idempotent. An archived credential cannot be
rotated back into use. Deleting a Vault also archives and clears all its credentials.
Delete responses contain id, deleted: true, and object: 'vault.deleted' or
'vault.credential.deleted'.
For Sandbox bindings, deletion or expiry blocks later launches that resolve the
credential. It does not remove values from existing processes or automatically
cancel a running Session. Polling, write_stdin, and cancellation remain
available. Deleting a Session does not delete its reusable Vault credentials.
Deleting a Vault credential does not revoke the token at its provider; your
application must call the provider when revocation is required.
List endpoints accept status=active or status=archived. Omitted status includes
both. Expiry does not archive a credential: an expired credential can still appear
in an active list. limit accepts 1–100 (default 20), order is asc or desc
(default desc), and after is a resource ID from the same scoped collection.
Responses contain object: 'list', data, has_more, first_id, and last_id.
Pass last_id as after with the same order for the next page.
Errors and recovery
HTTP errors use { error: { message, type, param, code } }. These are the relevant
validation and credential-resolution errors; execution-time failures appear in
tool or Turn results, not necessarily as an HTTP failure when input is submitted.
| HTTP status / code | Meaning and action |
|---|---|
400 invalid_request | Invalid fields, variable name, expiry format, or binding count. Correct the request; unknown credential fields are rejected. |
400 vault_not_attached | A binding's Vault is absent from vault_ids. Include it when creating the Session. |
400 invalid_auth_type | A Sandbox binding selects a different credential type, or rotation changes the type. Use the matching credential type. |
400 conflicting_environment_variable | Two bindings use the same name, or a binding overlaps environment.env. Use unique names. |
401 credential_expired | The Sandbox credential expired. Renew it with the provider and rotate the stored value before launching more work. |
401 credential_unavailable | A bound Sandbox credential was archived or its secret was removed. Create a new credential and a Session that binds it. |
409 credential_archived | Rotation targets an archived credential in an active Vault. Create a new credential; rotation cannot restore deleted secrets. |
404 not_found | The resource is missing, belongs to another organization, or the Vault is archived when active access is required. Check ownership and IDs. |
400 ambiguous_credential | Several service-origin MCP credentials match the URL. Select credential_id. |
401 invalid_api_key / 403 insufficient_scopes | Correct the organization key or grant the required API scope. |
SDK and protocol compatibility
sandbox_environment explicitly delegates a real secret to Sandbox code. It does
not implement OpenAI's environment_variable contract with a placeholder and
HTTPS proxy substitution. That capability remains unsupported. See
OpenAI compatibility
and Sandbox security.
Local verification on October 12, 2026 covered initial delivery, rotation within one Session, deletion, expiry, invalid bindings, organization isolation, and secret-free public resources using random test credentials and a real Rebyte Sandbox. This did not verify any provider's login or token-issuance flow.