End-user identity and credentials

When your backend calls the Runtype API with your API key, the request is authenticated as your Runtype account. Use end-user identity to associate each request with one of your end users. An agent can then scope memory, records, and secrets to that end user and use their connected permissions.

This guide explains two capabilities: verify an end user’s identity with Identity Exchange, and register a third-party account for that end user.

Use end-user identity for a multi-tenant product when each end user needs isolated data or a connected account. If every execution runs for your organization, use your API key without end-user identity.

How end-user identity works

Choose the capabilities that your product needs:

  1. Prove the end user’s identity. Send Runtype a proof that identifies the end user.
  2. Scope to the end user. Configure the agent to use that identity for memory, records, and secrets.
  3. Connect their accounts. Let an end user connect a GitHub account so Runtype stores and resolves the token under that identity during execution.

For a memory-only setup, pass a plain end-user ID. To isolate records and connected credentials, use a verified proof with the end-user-isolated Tenancy Strategy.

Prove an end user’s identity

Identity Exchange and Runtype-hosted identity produce the same durable end-user identity. Choose the method that matches your authentication setup.

Identity methodUse it whenWhat you provide
Identity ExchangeYou already have an identity provider, such as Clerk, WorkOS, Auth0, Okta, or your own OpenID Connect (OIDC) issuerAn integration that identifies your issuer and a token for each request
Runtype-hosted identityYou want Runtype to handle end-user sign-inA request to enable Runtype-hosted identity for your account

Use Identity Exchange with your identity provider

Identity Exchange brokers a token from your identity provider. Register the provider once, then send a short-lived token with each request. For oidc-jwt, Runtype checks the token against the provider’s public keys and maps the verified subject to an end user.

Register an integration with your issuer details. The Runtype API creates the integration id, which identifies the isolation namespace for that provider.

cURL
$curl https://api.runtype.com/v1/identity-integrations \
> -H "Authorization: Bearer rt_live_YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "name": "Example Organization OIDC",
> "provider": "oidc",
> "descriptor": {
> "kind": "oidc-jwt",
> "issuer": "https://example.com",
> "jwksUri": "https://example.com/.well-known/jwks.json",
> "audience": "example-runtype-client",
> "allowedAlgorithms": ["RS256"],
> "claimMap": {
> "subject": "sub",
> "email": "email"
> }
> }
> }'

Replace rt_live_YOUR_API_KEY with your live Runtype API key. Replace the example.com URLs with your issuer and JSON Web Key Set (JWKS) endpoint. This example uses oidc as the provider value.

The oidc-jwt descriptor in this example accepts the following fields:

FieldRequiredNotes
kindYesSet to oidc-jwt for a verifiable JSON Web Token (JWT).
issuerYesUse an https URL. Runtype selects the integration by the token’s verified issuer, not by the provider hint.
jwksUriYesUse an https endpoint that serves the issuer’s public keys.
audienceYesName a specific relying party. Wildcards are rejected.
allowedAlgorithmsYesUse asymmetric algorithms such as RS256 or ES256. Symmetric algorithms are rejected.
claimMapYesMap identity fields to token claims with dot notation. subject is required. tenant, email, roles, and permissions are optional.

Create only one active integration for each issuer in your account. The Runtype API rejects a second active integration for the same issuer in that account because issuer-based selection would be ambiguous.

Use Runtype-hosted identity

Use Runtype-hosted identity when you do not run an identity provider. Runtype hosts the sign-in page, brands it to your product, and issues an end-user token. Present that token as identityProof in the same way as a customer-issued proof. No integration setup is required on your side. Contact Runtype to enable this method for your account.

Pass a proof on a request

After you configure an identity integration, attach the end user’s proof to a dispatch or chat request as identityProof. Set provider to the integration’s provider value and token to the proof. For a Runtype-hosted token, use runtype-hosted as the provider value.

The following request dispatches a message to a saved agent with an end-user proof:

cURL
$curl https://api.runtype.com/v1/dispatch \
> -H "Authorization: Bearer rt_live_YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "agent": {
> "agentId": "agent_YOUR_AGENT_ID"
> },
> "messages": [
> {
> "role": "user",
> "content": "Summarize my open pull requests"
> }
> ],
> "identityProof": {
> "provider": "oidc",
> "token": "YOUR_IDENTITY_PROOF"
> }
> }'

Replace rt_live_YOUR_API_KEY with your live Runtype API key, agent_YOUR_AGENT_ID with the saved agent ID, and YOUR_IDENTITY_PROOF with a short-lived token from your identity provider.

When the proof verifies, the verified identity replaces any tenant or endUser value in the request body. For browser-embedded callers, the Runtype API does not trust body-asserted identity. Use a verified proof to receive a verified end-user scope.

Treat the proof token as a secret. Mint a short-lived token for each request. The Runtype API does not log, store, or echo it. Keep long-lived tokens out of client-side code.

For a browser-embedded widget, pass identityProof during session initialization. For more information, see Conversation history in an embedded widget.

Enable Identity Exchange admission for your organization before you send verified proofs. On dispatch and chat requests, the API accepts identityProof but ignores it when admission is disabled. Contact Runtype before you enable the strategy on an embedded surface.

A resource without a Tenancy Strategy keeps its existing scoping behavior. An end-user-isolated agent returns 403 when the request lacks a verified end-user identity. A trusted backend using a management API key can pass endUser directly.

Scope an agent to the verified end user

A verified proof establishes identity, but it does not configure an agent’s data scope. Set the saved agent’s Tenancy Strategy to end-user-isolated when you create or update the agent:

Agent config
1{
2 "config": {
3 "tenancyStrategy": {
4 "preset": "end-user-isolated"
5 }
6 }
7}

This preset requires a verified end user. Runtype rejects an execution that lacks one. When Runtype admits the execution, it applies the end-user scope to memory, records, and secret resolution. Keep this strategy on the saved agent definition. Do not accept it from an end-user-controlled dispatch body.

Connect an end user’s third-party account

Credential registration lets an end user connect a third-party account, starting with GitHub. The agent can then act with that account’s permissions. The connect request verifies the end user, redirects the browser to the provider’s consent screen, and the callback stores the resulting token under that end-user scope.

Complete the connection in two stages.

Start the connection

Call the connect endpoint from your backend with the end user’s proof. The Runtype API returns an authorization URL for the end user’s browser.

cURL
$curl https://api.runtype.com/v1/end-user-integrations/github/connect \
> -H "Authorization: Bearer rt_live_YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "identityProof": "YOUR_IDENTITY_PROOF",
> "redirectAfter": "https://example.com/settings/connections"
> }'

Replace rt_live_YOUR_API_KEY with your live Runtype API key. Replace YOUR_IDENTITY_PROOF with the end user’s proof. Replace the example.com URL with the page to open after the connection completes.

The response includes authorizeUrl, state, and endUserId:

Connect response
1{
2 "authorizeUrl": "YOUR_GITHUB_AUTHORIZATION_URL",
3 "state": "YOUR_OAUTH_STATE",
4 "endUserId": "eu_YOUR_END_USER_ID"
5}

The Runtype API generates authorizeUrl, state, and endUserId. The authorizeUrl value is the full provider URL. Treat these values as opaque, and redirect the browser to authorizeUrl without constructing the URL yourself.

Complete the connection

GitHub redirects the end user to the callback URL with an authorization code. The Runtype API exchanges the code for a token. It stores the token under the end-user scope and redirects the browser to the redirectAfter URL you supplied. You do not build the callback; Runtype provides the endpoint.

The end user has a stored credential scoped to their identity. If they reconnect, Runtype replaces the stored token.

Configure the provider’s OAuth app on your deployment before you call the connect endpoint. If it is not configured, the endpoint returns 501 Not Configured. Contact Runtype to provision a connector.

Use the stored credential

Runtype stores the token under a stable key scoped to the end user. A GitHub token uses the key GITHUB_TOKEN. Reference it in a tool configuration as you reference any secret:

Secret reference
{{secret:GITHUB_TOKEN}}

When an agent with the end-user-isolated Tenancy Strategy runs for a verified end user, {{secret:GITHUB_TOKEN}} resolves to that end user’s GitHub token. Each end user receives a separate value. If an end user has not connected an account, no value resolves. The key remains GITHUB_TOKEN for every end user; the end-user scope provides the isolation.

Scope memory without a proof

For a trusted backend without a Tenancy Strategy, authenticate with a management API key, set the agent’s memory profileTemplate to {{_endUser.id}}, and pass endUser.id in the dispatch body. This setup scopes memory only. It does not scope records or secret resolution, so do not use it for connected credentials. For browser-embedded callers, use a verified proof with the end-user-isolated Tenancy Strategy to isolate connected credentials.

Next steps

Use the following pages to continue: