Skip to main content
You can connect apps and manage credentials from either the web app or the CLI. Use the web app when you want a guided flow. Use the CLI when you’re scripting setup, working locally, or setting project-scoped credentials during deploy work.

Connect from the web app

Open Apps in the web app to see connected apps and add new ones. The Apps page is organized around credential instances: each connected app row represents a credential at an organization, project, or user scope. From there you can:
  • Connect an OAuth app (click “Connect an app” to see all available apps, and select an app to create a new connection).
  • Store an API key for an app.
  • Choose where the credential is available: organization, user, or selected projects.
  • Rename a credential, set it as default, rotate manual secrets, or revoke it.
OAuth connections open the provider’s authorization page. API key apps show a secret input and store the value in Keystroke’s credential vault.
Building over the Keystroke MCP server? The agent’s connect_app tool returns a link to this same web flow — a hosted workspace can’t open a browser, so you authorize the integration here.

Connect from the CLI

The CLI has two main paths:
CommandUse it for
keystroke connect <slug>OAuth-style connections, such as Slack
keystroke credentials set <key>Static API keys and manually-entered secrets
List connectable apps:
keystroke apps list
Connect an app. connect opens the web flow (OAuth approval or an API-key form, depending on the app), where you also choose the scope — there are no scope flags on connect:
keystroke connect slack
Store an API key:
keystroke credentials set exa --set apiKey=@env:EXA_API_KEY --scope org
--set accepts either an inline value (apiKey=sk-...) or an environment reference (apiKey=@env:EXA_API_KEY). Environment references load from the shell and the project’s .env file when available.

Credential scopes

Manual credentials set with keystroke credentials set take one or more scopes. (OAuth connections made with keystroke connect pick their scope in the web flow instead — the flags below apply to credentials set.)
Scope flagMeaning
--scope orgCreate an organization credential
--scope userCreate a credential for the authenticated user
--scope project --project-slug <slug>Create a credential for one project
If you omit --scope, the CLI creates an organization credential. You can repeat --scope and --project-slug to fan out one credential to several targets:
keystroke credentials set exa \
  --set apiKey=@env:EXA_API_KEY \
  --scope org \
  --scope project \
  --project-slug production \
  --project-slug staging
Project scope requires --project-slug because the credential must be written to a specific platform project.

Local vs cloud

Credentials follow the CLI’s active target:
# Local server credential
keystroke --local credentials set exa --set apiKey=@env:EXA_API_KEY

# Cloud platform credential
keystroke credentials set exa --set apiKey=@env:EXA_API_KEY --scope project --project-slug production
Deploy does not upload .env or local credentials. For deployed runs, set credentials against the cloud target with the web app or CLI. Workers materialize the selected credential from the platform when an action runs.

Manage credentials

Use the Apps page for day-to-day management, or use CLI commands when scripting.
keystroke credentials list
keystroke credentials get <credential-id>
keystroke credentials update <credential-id> --label "Production Exa" --default
keystroke credentials rotate-key <credential-id> --set apiKey=@env:EXA_API_KEY
keystroke credentials delete <credential-id>
A few details:
  • rotate-key is for cloud credentials and replaces a manual secret value.
  • update --default marks one credential as the default within its app and scope.
  • If multiple credentials exist for the same app and scope and none is the single default, a run needs an explicit selection — bind one with an assignment (below).

Bind a credential to a step, tool, or poll action

A default resolves the common case, but sometimes one workflow step, agent tool, or poll action must use a specific instance — a particular project’s Linear connection, a dedicated service account, one of several org credentials. An assignment pins an exact credential instance to a single consumer. It is the explicit selection at the top of the resolution order, so it wins over scope defaults. First list the bindable consumers for a workflow, agent, or poll, then assign:
# Workflow consumers are step correlation ids from recent runs (step:<slug>#<n>)
keystroke credentials consumers list --workflow sync
keystroke credentials assignments assign --workflow sync --credential org/work --consumer step:fetch-gmail#0

# Agent consumers are tool slugs
keystroke credentials consumers list --agent support
keystroke credentials assignments assign --agent support --credential vault-prod --consumer vault-lookup

# Poll consumers are the slugs of actions called inside the poll's run()
keystroke credentials consumers list --poll new-inbox
keystroke credentials assignments assign --poll new-inbox --credential gmail/support --consumer fetch-inbox
  • Pass exactly one of --workflow <slug>, --agent <slug>, or --poll <slug>.
  • --credential takes a credential instance slug: work, org/work, or <app>/<slug> (for example linear/work).
  • Omit --consumer (or pass *) to bind every consumer on the target instead of one.
Inspect and remove assignments:
keystroke credentials assignments list --workflow sync
keystroke credentials assignments unassign <assignment-id>
Workflow consumer ids come from step_completed events, so they appear only after the workflow has run at least once. Agent consumers include known tool slugs plus any from existing assignments. Poll consumers only come from existing assignments — name the action slug explicitly (or use the wildcard) on the first assign.

External channel apps

External channel apps connect agents to chat tools. Slack is the primary one today. You connect Slack like any other app, then bind channels to agents from the agent’s channel panel or the CLI:
keystroke channels bind \
  --agent support \
  --platform slack \
  --account <workspace-id> \
  --channel <channel-id> \
  --mode mention
See external channels for the agent-facing Slack setup.

Next steps

Built-in integrations

Understand the app catalog and managed integration paths.

Using credentials in code

Control how actions resolve credentials at runtime.

External channels

Connect Slack channels to agents.

CLI reference

See every credential, connect, channel, and API key command.