@agent-core

Bring your own keys

Set your own API keys and secrets from the chat config panel — self-service, user-scoped BYOK, no admin required.

Some work needs a key only you have — your personal OpenAI key, a token for a service only you are licensed for, a secret a skill you use expects. You do not have to file a ticket with an administrator for that. The chat config panel's Credentials card lets you store your own secrets, in your own scope, and use them immediately.

This is bring-your-own-key (BYOK): a self-service surface for the credentials.self capability, which managers and members hold by default. It sits alongside the Channels, Git remotes, and MCP servers cards in the same panel, and it is a sibling — not a replacement — of the owner-run admin Credentials tab.

Where it lives

Open the chat config panel and expand the Credentials section. If you hold credentials.self, you see it; if your role in this project does not grant the capability, the card is not rendered at all. The header shows how many of your listed credentials currently have a value (e.g. 2/5).

What the list shows

The card lists two things merged into one view:

  • Declared credentials you can see — every id declared by a package or skill that is visible to you in this project. A package declares the secrets it needs in its manifest; a skill declares them in its frontmatter (see the manifest credentials array). Each row names the id, its category, and which package or skill requires it.
  • Your own custom ids — anything you added yourself that no package or skill declares.

Visibility follows the platform's normal deny-by-default rule: you only see credentials declared by packages and skills that are already visible to you. A package you are feature-hidden or scope-hidden from never reveals its credential ids here — the card cannot be used to enumerate capabilities you have no access to. If the platform cannot confirm what you may see, it shows nothing rather than risk a leak.

Each row shows a set / not set badge. That flag reflects only your own user scope — it tells you whether you have stored a value, never whether an owner set a project or platform value behind the scenes.

Setting a value

Click Set (or Replace) on a row, paste the value, and save. To store a key that no package declares, click the + button and enter an id of your own — any well-formed id (letters, digits, _, ., -) works, for example OPENAI_API_KEY or llm.openai.

Values are write-only. Once saved, the value is never shown again — the card, and the whole API, only ever report whether a value is present. To rotate a key, set a new value over the old one; to remove it, use the trash button on the row.

Everything you set lands in your own user scope and nowhere else. There is no scope picker: the surface cannot write to another user, a project, or an agent. That is a structural guarantee, not a UI convenience — the route hard-codes your identity and the server re-checks it on every write.

How your key gets used

A stored user-scope credential becomes your BYOK value for any package or skill that resolves that id while running as you. Resolution is most-specific-wins — agent → project → user → global (see Credentials) — so:

  • if no agent- or project-scope value exists, your personal key is used;
  • if an owner set a project or agent key, that key always wins over your personal one inside that project. Your BYOK key is a personal fallback, never an override of a value an administrator pinned.

One family never reads your scope: the embedding keys (embedding.*). Indexing runs as background platform work with no user in context, and one vector collection serves every project, so those ids resolve at the platform (global) scope only — a value you store under one of them is kept but never used. Ask an owner to set the platform key instead.

What you cannot set here

Reserved integration secrets are excluded from this card and rejected if you try to add them by hand:

  • git remote tokens (git.<host>.…) — use the Git remotes card,
  • channel secrets (telegram.…, whatsapp.…) — use the Channels panel,
  • outbound MCP secrets (mcp.<server>.…) — OAuth tokens, app client secrets, sidecar env values and secret request headers all live on the MCP servers card, on the row of the server that uses them.

These live on their own connect surfaces because each needs extra validation — live token checks, per-connection derived ids, OAuth callbacks — that a plain value field cannot provide.

If the group disappears

An owner can turn off member self-service for a project by removing the credentials.self capability from that project's roles. When that happens the Credentials group is no longer shown and new writes are refused in that project. A value you stored while the capability was granted keeps working — user scope is global to you, so an already-set key still resolves. If a value must be removed entirely, an owner deletes it from the admin Credentials surface.

Security in one line

Your keys are encrypted at rest, scoped to you, never echoed back, and every set or delete is recorded in the audit log by id — never with the value. The full model, including the owner/admin all-scope surface, is on the Credentials page.

On this page