Declare credentials on an action
For a new credentialed custom integration, preferdefineApp so the credential lives on the app and actions use app.action(...). This page shows the lower-level shape: a credential declaration listed on defineAction, which is what defineApp produces under the hood — and what you may still use for rare shared secrets that are not one service.
src/actions/search.ts
exa) is the app/credential slug Keystroke looks up in the vault. The schema validates the resolved secret before your action runs.
Credentials belong on actions (or on an app that binds them to actions), not on
defineAgent() or defineWorkflow(). Agents and workflows get credentials by running actions that declare them. Actions with no secrets stay as plain defineAction — no app required.Credential kinds
There are three runtime credential kinds:
Most custom API keys are authored via
defineApp({ auth: "api_key", credential: … }). Built-in app packages usually define the credential for you. Standalone defineCredential is for edge cases — see custom apps and MCP.
Use actions in workflows and agents
Once an action declares credentials, use it like any other action.Resolution order
When an action runs, Keystroke resolves each credential requirement using the run context. Resolution order:- Explicit selection: a credential assignment (or other platform-supplied instance id) for this consumer wins.
- Pinned scope: if the action or credential is scoped with
.scope(...), only that scope is tried. - Project default: for unpinned credentials, try the default project credential.
- Organization default: if no project credential resolves, try the default organization credential.
- Error: if nothing resolves, the run fails with a missing-credentials error.
.scope("user") on the action, then assign a user credential to that workflow step, agent tool, or poll consumer.
Pin a scope
Use.scope() when the action must use a specific credential scope.
Pinning
.scope("user") alone does not pick a person or pull identity from the run. Associate a user credential with the step, tool, or poll consumer via an assignment (keystroke credentials assignments assign or the API). Without that assignment, the run cannot resolve the user credential.
If a pinned scope has no matching credential (or assignment), Keystroke does not fall back to another scope.
Defaults and multiple credentials
Within a scope, Keystroke can resolve a credential automatically when:- There is exactly one credential instance for that app and scope.
- Or there are multiple instances, but exactly one is marked as default.
Troubleshooting
When a credential can’t be resolved, the action fails beforerun executes, with a message that points at the fix:
For
.scope("user"), connect a user-scoped credential and assign it to the workflow step, agent tool, or poll consumer. User scope is not inferred from a run actor or actorId. The Slack gateway runs as the workspace’s connected account, not the individual who sent the message, so prefer organization or project scope there unless you have assigned a specific user credential.
Credential stores
Credentials live in the hosted platform credential store and are materialized to workers on demand. Deploying a project does not upload.env. If a deployed workflow uses an action with credentials, connect those credentials in the cloud first.
Next steps
Connect and manage apps
Create credential instances and choose their scopes.
Actions
Learn how actions define typed inputs, outputs, and credentials.
Workflow steps
Run credentialed actions as durable workflow steps.
Agent tools
Attach credentialed actions as tools an agent can call.