Skip to main content
A credential is a secret Duraton stores on your behalf (an API key, an OAuth token, SMTP settings) so a workflow can call a third-party service without the credential living in an environment variable. client.credentials.resolve() reads one back at execution time.

Resolve inside a step

Resolution must happen inside a step.run (or step.ai.*) closure, never in the workflow handler’s top-level body. A step’s input and output are durable - they are recorded and replayed forever - so a credential resolved outside a step, then passed into one, would sit in that replayed record permanently. Resolved inside the closure, the credential is used only for the one call that needs it and is gone once the step returns:
resolve() called outside a step - directly in the handler body, or stashed in a variable before a step.run call - throws immediately (CredentialResolveOutsideStepError) rather than silently handing back a credential with no durable-input protection.

Auth shapes

authShape tells you how to read credential and how to present it to the third party. A single-value shape is the value itself; a multi-field shape is a JSON string you parse yourself. header_auth and query_auth are distinct shapes rather than an api_key with a placement setting, because placement changes how you use the credential, not just what its bytes are - so it travels in the shape rather than hidden inside the blob. A replayed step never re-invokes its body, so a memoized resolve() call never runs twice and never fails if the credential was since deleted - it only had to exist at the moment the step first ran.

Retrying a rejected credential

Duraton refreshes an OAuth credential’s access token ahead of its known expiry, so a normal resolve already returns a live token. A token can still be rejected by the provider despite looking valid (clock skew, early revocation) - catch that in the step and let the step’s own retry call resolve() again:
The second attempt calls resolve() again from scratch, picking up a refreshed token if one is due. A token rejected well before its known expiry (the provider revoked access early) is not fixed by a retry - the credential needs re-authorization; see Retries & failure handling for NonRetriableError to fail fast on that case instead of spending the retry budget.