Authentication Reference authentication-reference

IMPORTANT
Adobe LLM Apps is currently in Beta.
Features, workflows, and UI shown here do not necessarily represent the final state of the product. To join the Beta, send an email to llm-apps-beta@adobe.com.

Use this page to look up authentication fields and contracts. For the setup journey, see Authenticate end users with your own identity provider.

Authentication settings authentication-settings

Found under Settings > Authentication. Every field is stored per environment — the Workspace picker selects which one you are editing, and saving never affects the other.

Field
Required
Description
Workspace
—
Which environment these settings apply to: Stage or Production
Enable authentication
—
Master switch. When off, every action is public regardless of its auth mode
Issuer
Yes
Your identity provider’s issuer URL, and the expected iss claim. Must be HTTPS. Also published as this app’s authorization server. One identity provider per app
Scopes supported
No
The complete set of scopes this app’s actions may require. Published to LLM platforms as the app’s supported scopes
JWKS URI
No
Advanced. The HTTPS URL of your signing key set. Only needed when it differs from what your authorization server’s metadata advertises

Validation rules

Rule
Effect
Issuer is empty while Enable authentication is on
Save is blocked
Issuer or JWKS URI is not an HTTPS URL
Save is blocked
An action requires a scope missing from Scopes supported
Save is blocked until you add the scope or remove it from the action
A scope is removed from Scopes supported
It is removed from every action that required it, immediately, without waiting for a save
Scopes supported is empty
No scope can be granted, so any scope already on an action is removed. No warning is shown in this case
offline_access is listed in Scopes supported or on an action
Removed when the app is deployed, regardless of casing or surrounding whitespace, so the settings page can show a scope the deployed app does not have. offline_access requests a refresh token from your authorization server rather than granting access to this app, so it is not a scope this app advertises. You do not need to list it — the LLM platform requests it from your authorization server directly

Trailing slashes on Issuer are normalized, and the iss comparison tolerates the difference — a provider that always emits a trailing slash still validates.

Auth modes auth-modes

Set per action under Per-action configuration.

Mode
Token required
Handler receives identity
Advertised to the platform as
None
No
Only when the caller supplies a valid token
noauth
Required
Yes, with every listed scope
Always
oauth2
Optional
No
When a valid token is present
noauth and oauth2

A Required action’s handler never runs without a valid, correctly scoped token. An Optional action’s handler always runs, and may request sign-in itself with extra.challengeAuth().

Required is therefore the only mode that refuses unauthenticated callers. An app is fully gated only when every one of its actions is Required; a single None or Optional action makes the app mixed, because anonymous calls still succeed for at least one action.

Auth modes are only in force when Enable authentication is on. Changes take effect on the app’s next deploy.

Toggling that switch rewrites the per-action modes:

Switch change
Effect on per-action modes
Off to on
Every None action becomes Required. Actions already Required or Optional keep their mode
On to off
Every action’s mode and scopes are cleared for that environment. The configuration is not restored if you turn the switch on again

Switching Workspace never rewrites modes — it loads the other environment’s saved configuration as-is.

Enable authentication on with every action set to None is a valid but inert combination: no call is ever refused, yet the app still publishes its authorization server for discovery. Turn the switch off to make the app fully public.

Modes can be mixed freely across one app. See LLM platform behavior for how each platform applies them.

Token requirements token-requirements

Your identity provider must issue access tokens that satisfy all of the following. A token that fails any check is treated as absent — the caller is unauthenticated, and a Required action challenges them to sign in.

Requirement
Detail
Format
Signed JWT. Opaque tokens are not supported
Signing algorithm
RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, or PS512. HMAC algorithms such as HS256 are rejected
iss
Must match Issuer
aud
Must contain the app’s resource identifier — its MCP server URL for that environment
exp
Must be in the future
scope or scp
Space-delimited string, or an array of strings. Supplies the scopes checked against each action’s requirements
sub
The user identifier your handler reads through getAuthenticatedUser
Transport
Authorization: Bearer <token> request header

Any additional flat claims your provider includes — for example tenant or email — are passed through to your handler. Nested objects are dropped, and long string values are truncated.

Identity provider discovery discovery

Your app publishes its own RFC 9728 protected resource metadata so LLM platforms can locate your authorization server. You do not create, host, or configure anything for it.

You must provide discovery on your own side:

Requirement
Detail
Authorization server metadata
Your issuer must serve its own RFC 8414 metadata, or OpenID Connect Discovery, at its /.well-known/ path. Your app reads it to locate your signing keys
An issuer with a path
The well-known segment goes before the path, not after it. An issuer at https://auth.example.com/oauth2/default serves its metadata at https://auth.example.com/.well-known/oauth-authorization-server/oauth2/default
Keys hosted elsewhere
Set JWKS URI when your signing keys are not where that metadata advertises them

Handler auth API handler-auth-api

Exported from @adobe/llm-apps-runtime. Each helper takes extra, the second argument your handler receives.

Helper
Returns
getAuthenticatedUser(extra)
The signed-in user’s sub claim, or undefined when the call is unauthenticated
hasScope(extra, scope)
true when the caller’s token carries scope

The raw verified token information is on extra.authInfo, which is undefined for an unauthenticated call.

Property
Description
authInfo.token
The raw bearer token. Do not log it or return it to the client
authInfo.clientId
The client_id or azp claim, or unknown
authInfo.scopes
Array of granted scopes
authInfo.expiresAt
Token expiry, as the exp claim
authInfo.resource
The app’s resource identifier that the token was validated against
authInfo.extra
sub plus any other flat claims your identity provider included

extra.challengeAuth(options) is available only on Optional actions. Return its result from your handler to ask the user to sign in instead of returning content.

Option
Description
error
An RFC 6750 Bearer error code: invalid_token, insufficient_scope, or invalid_request. Defaults to insufficient_scope
errorDescription
The message shown to the user. Defaults to a generic sign-in prompt
scope
Space-delimited scopes to request. Omit it to let the platform fall back to the app’s supported scopes
IMPORTANT
Always set error explicitly. Use invalid_token for a caller with no valid session, and insufficient_scope only for a caller whose token is valid but lacks a required scope. The value is passed through to the LLM platform, which decides for itself how to word the prompt it shows the user. Send the code that accurately describes the condition rather than the one whose prompt you would prefer.

LLM platform behavior platform-behavior

Support for authenticating individual actions varies by platform. Configure the same way for both; the difference is what the user experiences.

Behavior
ChatGPT
Claude
Granularity
Per action
Per connector
Mixed authentication, where the app is not fully gated
Supported. Only the Required actions prompt for sign-in
Not supported. The whole connector prompts for sign-in, including the ungated actions
Connector setup
Set Authentication to No Auth when every action is None, OAuth when every action is Required, and Mixed otherwise
No auth choice to make; sign-in starts on Connect
Re-authentication
Prompted in the conversation when a gated action is called
Prompted for the connector
recommendation-more-help
llm-apps-help-main-toc