Skip to content

Credentials

Everything Tenbi does on your behalf — running Claude agents, reading tickets, pushing branches, opening PRs, posting notifications — is done with credentials you provide. This chapter covers all of them: the Anthropic credential that powers the agents, the reusable service credentials your modules attach to, and how Tenbi stores, verifies, rotates, and deletes secrets.

All of it lives in one place: Settings → Credentials (the gear in the top bar).

Two rules apply to every secret on this page:

  • Encrypted, write-once. Secrets are encrypted at rest (AES-256-GCM) and never shown again after saving — the UI only ever displays the last few characters (•••• abcd) so you can tell which secret is loaded.
  • Yours alone. Tenbi is multi-tenant: credentials belong to your account, are invisible to every other account, and can only be attached to your own modules. Runs bill your credential or they fail — they never borrow anyone else's.

The Anthropic credential

Every run is a team of Claude agents working your ticket, and they run on your Anthropic credential — Tenbi never marks up or meters your usage. This credential is required: an account without one can't run anything. Runs fail immediately with an authentication error that links you back to this page (see Model key invalid for the triage steps).

It sits at the top of Settings → Credentials, under Anthropic. There are two auth modes; the API key is the one to use.

An API key from the Anthropic Console is the supported way to run Tenbi — as the UI puts it, it's the path Anthropic's terms support for third-party products.

  1. In the Anthropic Console, create an API key (you may need to set up billing first).
  2. Paste it into the Anthropic API key field and press Save.

What to expect on a metered key:

  • Billing — runs bill per token, by Anthropic, to you, at their standard prices. A typical run costs a few dollars; every run's cost is visible in Analytics.
  • Capacity — isolated. There's no shared usage window to exhaust, so run volume and your own personal Claude use never collide.
  • Model access — the key must have access to whatever model your runs select; a key without access to the selected model fails the run with an auth error, same as a missing key.

Picking a default model

The model is the biggest cost/quality lever you have. It's set in Settings → General, under Default model — the change saves automatically, no Save button. The default choice, Runner default (Claude Code decides), lets the runner pick; individual Lanes can override the model per-Lane, and a Lane override takes precedence (see Lanes).

In subscription (OAuth) mode, the model must be one your Claude plan includes.

Advanced: subscription (OAuth) authentication — at your own risk

Tenbi can also run against a Claude Pro/Max subscription via an OAuth token instead of an API key. This mode exists, but it is deliberately tucked behind an Advanced: subscription (OAuth) authentication expander, and you should understand exactly what you're accepting before opening it.

This mode is not supported by Anthropic's terms. Anthropic's Consumer Terms prohibit using Claude subscription credentials in third-party services (§2, §3.7; clarified February 2026), and Anthropic enforces this with automated account suspensions. Using a subscription token with Tenbi can get your Anthropic account banned — mid-run, without warning. Tenbi cannot prevent or reverse this. The supported path is an Anthropic API key.

The one-time acknowledgment. Before a subscription token can be saved or the mode enabled, you must check the acknowledgment: I understand this may violate Anthropic's Terms of Service and I accept the risk to my Anthropic account. This isn't a cosmetic checkbox — the server enforces the same gate and rejects the save (HTTP 422) without it. Once acknowledged, the panel shows Risk acknowledged on the date instead, and you won't be asked again.

The usage-window caveat. A subscription is flat monthly cost, but runs share your subscription's rolling usage windows with everything else on that account. Heavy run volume — or running Tenbi alongside your own Claude use — can exhaust a window mid-run, and those runs fail as rate limited until the window resets.

Getting the token (one time, ~2 minutes, on any machine with the Claude Code CLI installed):

  1. Run claude setup-token in a terminal.
  2. It opens (or prints) a claude.ai authorization link — open it, sign in if asked, click Authorize.
  3. The browser shows a code — paste it back into the terminal prompt.
  4. The terminal prints a long-lived token starting with sk-ant-oat… — paste it into the Claude Code OAuth token field.

Which account gets billed? The token belongs to whichever account that terminal's Claude Code is signed into. If you have more than one (say, work and personal), run claude /status first to check — you're about to point every Tenbi run at that subscription.

To activate the mode, flip Use subscription (OAuth) mode for runs and press Save. OAuth tokens expire — when a working setup starts failing runs with auth errors, generate a fresh token with claude setup-token and re-paste it.

A note on cost figures in this mode: per-run dollar amounts shown in Tenbi are the API-equivalent value of the usage — an estimate of what the run would have cost on a metered key, not a bill. Spend totals in Analytics count metered runs only.

Mode selection — there is no fallback

Only the credential for the selected mode is ever used. You can keep both secrets stored and switch modes any time — switching is instant and reversible — but:

  • Selecting OAuth mode with no token saved fails your runs with an authentication error even if an API key is on file, and vice versa.
  • Tenbi never falls back across accounts: your runs bill your credential or they fail.

Reusable service credentials

Below the Anthropic section, Reusable credentials holds the secrets for the services your tickets and repos live in — GitHub, Jira, Bitbucket, and so on. They're reusable on purpose: you enter a secret once, and any number of modules can point at the same credential. That's also what makes rotation painless — replace the token in one place and every module using it picks up the change.

To add one, press Add, pick a Type, give it a Name (e.g. GitHub — personal), fill in the fields, and press Create. For most types there's a Verify button right on the form — use it as you go; a credential verified at creation time is far easier than debugging a failed run later.

What each type needs

TypeFieldsMinimum access
GitHub PATPersonal access tokenClassic: repo scope · Fine-grained: Contents R/W, Pull requests R/W, Metadata R (+ Issues R/W for Ticketing)
Jira CloudSite URL, Account email, API tokenYour Jira user's project access
ShortcutAPI tokenYour workspace access
Bitbucket CloudAccount email, API tokenRepositories R/W, Pull requests R/W
Azure DevOps PATPersonal access tokenCode: Read & write
Discord webhookWebhook URL
Slack webhookWebhook URL

GitHub PAT

Used by GitHub Ticketing and Version Control modules. One field: Personal access token (ghp_… or github_pat_…). Scopes are the single most common setup failure, so get them right up front:

  • Classic PAT — the full repo scope. public_repo is not enough: private repos become invisible and read as 404s. The same repo scope also covers issues for Ticketing use.
  • Fine-grained PAT — three things must all line up:
    • Resource owner is the account/org that owns the repo (a personal token can't see org repos unless the org allows it).
    • Repository access explicitly includes your target repos — the default allow-list silently excludes repos created after the token.
    • Permissions: Contents: Read and write, Pull requests: Read and write, Metadata: Read — plus Issues: Read and write if the same token backs a Ticketing module.

404 means scopes, not "missing". On GitHub, a private repo your token can't see returns 404, not 403 — "not found" almost always means the token's scopes or fine-grained allow-list, not that the repo doesn't exist. Full fix steps: VCS repo not found.

One quirk worth knowing: editing a fine-grained token's repository access on GitHub does not change the token value — you don't need to re-paste anything in Tenbi. Fix the access on GitHub and press Verify again.

Workflow files need an extra scope. If your tickets might change files under .github/workflows/ (GitHub Actions CI/CD definitions), the token needs GitHub's workflow permission or the push is rejected — even with full repo access. Classic PAT: also check the workflow scope. Fine-grained PAT: set Workflows: Read and write. Without it, a run does all its work but fails at the final push with "refusing to allow a Personal Access Token to create or update workflow … without workflow scope." Full fix: Workflow file push rejected.

Jira Cloud

Used by Jira Ticketing modules, if your tickets live in Jira. Three fields: Site URL (e.g. https://yoursite.atlassian.net), Account email, and API token (an Atlassian API token, created in your Atlassian account settings). The token inherits your user's project access — if you can't see a project in Jira, neither can Tenbi.

Shortcut

Used by Shortcut Ticketing modules. One field: API token. It inherits your workspace access; Verify confirms it by reporting the authenticated member.

Bitbucket Cloud

Used by Bitbucket Version Control modules. Two fields: Account email and API token, with Repositories: Read and write and Pull requests: Read and write permissions.

Azure DevOps PAT

Used by Azure Repos Version Control modules. One field: Personal access token, with Code: Read & write at minimum. Two things are different about Azure:

  • The organization is not on the credential — it's set on the Version Control module, and repos are named project/repo (not owner/repo).
  • There's no standalone Verify button for this type. An Azure PAT is org-scoped, so there's nothing to check it against on its own — it gets verified when you press Verify on a repo row (on the module or the Lane), which checks the PAT against a real repo.

Discord / Slack webhooks

Used by Messaging modules, only if you want run notifications posted to a channel. One field each: Webhook URL. Paste the webhook URL from your Discord or Slack channel settings. These can't be verified without actually sending a message, so the form tells you so instead of offering Verify — you'll know it works when the first notification arrives.

Verifying

Verify runs a live check against the provider — it's the difference between "the token is saved" and "the token works." Two behaviors worth knowing:

  • You can re-verify a stored credential without re-pasting it. Open the credential with Edit, leave the masked secret untouched, and press Verify — the stored secret is checked as-is. Do this after changing anything on the provider side (scopes, repo access, SSO authorization).
  • Failures tell you why. A failed verify shows the provider's rejection and links to the matching fix — scopes for access problems, and a distinct expiry hint when a previously-working credential stops verifying (expiring token types: fine-grained GitHub PATs, Azure PATs, Anthropic OAuth tokens).

Verifying a credential is separate from verifying a repo — repo rows on Lanes and Version Control modules have their own Verify, which checks that this credential can reach that specific repo (and its base branch, when one is set).

How secrets are stored — and what you'll see later

Encryption at rest. Every secret — the Anthropic key, OAuth token, PATs, API tokens, webhook URLs — is encrypted with AES-256-GCM before it's stored. Non-secret fields (a Jira site URL, an account email) stay readable in the list; the secret itself never leaves the server again in any form.

Never shown again. After saving, the UI renders a saved secret as a masked value with its last few characters (•••• abcd) — enough to tell which key is loaded, never the key itself. There is no "reveal" — if you need the value, get it from the provider that issued it.

Replacing a secret. A saved secret field shows the mask with a Replace button. Press it to type a new value; Cancel — keep current secret backs out. Leaving a masked field untouched on save always means "keep the existing secret" — you never need to re-enter a secret just to rename a credential or edit its other fields.

Rotation is a one-field edit. When a token expires or you rotate it at the provider: Edit the credential, Replace the secret field, paste the new value, Save, Verify. Every module pointing at that credential picks up the new value immediately — nothing else to touch. This is the payoff of reusable credentials: rotate once, not once per module.

Deleting. Delete on a credential row asks for confirmation and is permanent — "This cannot be undone."

Delete doesn't check what's still attached. Deleting a credential that a module still references breaks that module — its verifies and runs start failing until you point it at another credential. Detach or re-point modules first. And note there's no disable switch on a credential: if you want to pause work rather than tear it down, disable the Lane instead (the Enabled toggle on the Lane) and leave the credential alone.

If a run fails on credentials

The failure callout on the record names the cause and links to the fix. The credential-shaped ones:

SymptomWhere to look
Run fails in seconds with an auth error, or "Anthropic credential needed"Model key invalid
Repo verify or clone fails with not found / 404VCS repo not found
Verify fails with 401/403, or a long-working Lane suddenly fails authPAT scopes and the auth sections around it

Once the credential is fixed, press Rerun on the record — reruns re-fetch the ticket and start fresh.

Where to go next

With your Anthropic credential and service credentials saved and verified, the next step is wiring them into Modules — the Ticketing and Version Control building blocks a Lane attaches to. The full zero-to-first-PR walkthrough is in First Steps.