- Public anonymous SDK
- Runtime-signed Hosted Exchange bootstrap
- Customer-issued shared-secret JWE
- Customer-issued public-key JWE with customer-signed payload
Before you set up E2E auth, install the Agent Platform SDK.
Scenario Selection
Public-key customer JWE has two layers:
- The outer JWE gives confidentiality to Runtime using
RSA-OAEP-256andA256GCM. - The inner JWS gives issuer authentication using the customer signing private key and Runtime-configured customer signing public key.
Shared Runtime Flow After Bootstrap
All four scenarios converge after browser initialization:Permission And Origin Resolution
Public API key permissions are stored as coarsechat and voice booleans.
Runtime expands them to SDK permissions:
Runtime-signed Hosted Exchange tokens derive permissions from the channel’s
active public API key. The
/api/v1/sdk/customer-sessions request body does not
accept permissions.
Customer-issued JWE payloads may include a narrower permissions array. Runtime
normalizes the requested values, adds session:read for interactive or
attachment grants, intersects the requested set with the channel’s active public
API key permissions, and rejects the token if the effective set is empty.
Allowed customer-issued permission values:
session:send_messagesession:voicesession:readattachment:readattachment:writeattachment:delete
- Public-key SDK init checks the public API key origins and, if present, legacy channel-config origins.
- Hosted Exchange bootstrap init checks both the channel-config origins and the bound public API key origins after the bootstrap token is verified.
- Empty or unset allowed-origin lists behave as unrestricted in code. Production channels should always configure explicit HTTPS origins.
Shared Studio Prerequisites
- Create or select the project that owns the SDK channel.
- Create or select the deployment the SDK channel should route to.
- Create or select a public SDK API key for the project.
- Set allowed origins on the public API key or managed channel key.
- Include the exact browser origins that will host the SDK.
- Do not rely on wildcard origins for production flows.
- Create an SDK channel and bind it to the deployment or environment.
- Keep the channel active only after customer backend and browser changes are deployed.
anonymousfor public anonymous SDK.hosted_exchangefor Runtime-signed, customer-issued shared-secret JWE, and customer-issued public-key JWE.
Shared Deployment Prerequisites
Runtime must have:JWT_SECRET,AUTH_SDK_BOOTSTRAP_SIGNING_SECRET, andAUTH_SDK_SESSION_SIGNING_SECRETconfigured consistently across Runtime pods.ENCRYPTION_MASTER_KEYconfigured when Hosted Exchange token envelope JWE is required or preferred.AUTH_SDK_JWE_ENABLEDunset ortruewhen JWE issuance/verification should be available.REDIS_URLconfigured for distributed SDK session state, WebSocket tickets, replay protection, and rotation locks.- MongoDB available for SDK channel, public key, and customer JWE key metadata.
- HTTPS between browser, customer backend, and Runtime.
jwe_required is configured and capability is not ready, Runtime must fail
closed instead of returning signed Hosted Exchange tokens.
Scenario 1: Public Anonymous SDK
Studio Setup
- Open the project deployment channel settings in Studio.
- Create or edit an SDK channel.
- Set SDK auth mode to
anonymous. - Bind the channel to the target deployment or environment.
- Configure allowed origins for the browser site.
- Save the channel.
- Copy the public SDK API key and channel identifier or channel name.
sdkTokenEnvelopePolicy or customerIssuedJwe on anonymous
channels. Runtime rejects those settings unless auth.mode=hosted_exchange.
Customer Server Changes
No customer server auth endpoint is required. The server that renders the website may provide public configuration values such as:- Runtime endpoint
- Project ID
- Public SDK API key
- Channel ID or channel name
- Deployment slug, when the channel uses deployment-slug selection
Browser SDK Changes
Core SDK:Validation
- Load the browser site from an allowed origin.
- Confirm
/api/v1/sdk/initusesX-Public-Key. - Confirm the request body does not include
bootstrapToken. - Send a chat message.
- Confirm
/api/v1/sdk/ws-ticketsucceeds before WebSocket connect. - Disable the channel or remove the origin and confirm new sessions fail.
Scenario 2: Runtime-Signed Hosted Exchange
This path adds a customer backend endpoint, but lets Runtime mint the bootstrap artifact. The browser never sees the Hosted Exchange channel server secret.Studio Setup
- Open the project deployment channel settings in Studio.
- Create or edit an SDK channel.
- Set SDK auth mode to
hosted_exchange. - Configure allowed origins.
- Select
sdkTokenEnvelopePolicy:signedfor signed-token compatibility.jwe_preferredfor rollout where JWE is used when Runtime capability is ready.jwe_requiredafter the capability endpoint shows Runtime can issue and verify JWE.
- Save the channel.
- Copy the Hosted Exchange server secret when Studio reveals it.
- Store the server secret only in the customer backend secret manager.
Customer Server Changes
Add a backend endpoint that authenticates the customer in the customer’s system, then calls Runtime:- Send exactly one of
channelIdorchannelName. - Do not send
permissions; Runtime derives the effective SDK permissions from the channel’s active public API key. - Keep
customAttributeswithin the SDK user context size limits. Runtime returnsSDK_TOKEN_TOO_LARGEwhen normalized custom attributes exceed the token budget.
channelName variant:
sdkTokenEnvelopePolicy resolves to JWE, tokenEnvelope is "jwe" and
bootstrapToken is a 5-segment compact JWE.
Recommended customer backend controls:
- Authenticate the website user before minting a bootstrap token.
- Collect sensitive data and secure custom attributes server-side only.
- Keep
verifiedUserIdstable for the customer identity. - Keep the endpoint same-origin or protected by customer auth cookies.
- Do not return the channel server secret to the browser.
- Do not log
bootstrapToken, sensitive data, or secure custom attributes.
Browser SDK Changes
Use abootstrapTokenProvider so each fresh init gets a new short-lived token:
bootstrapTokenProvider property before appending the custom element.
The widget reads SDK config during its connection/bootstrap lifecycle.
Validation
- Customer backend calls
POST /api/v1/sdk/customer-sessions. - Browser calls
/api/v1/sdk/initwithbootstrapTokenand withoutX-Public-Key. - Runtime returns an SDK session token.
- If
sdkTokenEnvelopePolicy=jwe_required, confirm returned Hosted Exchange bootstrap/session material is JWE or the flow fails closed. - Replay the same bootstrap token and confirm Runtime rejects it.
- Confirm SDK refresh and WebSocket ticket flows succeed.
Scenario 3: Customer-Issued Shared-Secret JWE
This flow requires no new Artemis API call: the customer backend pulls secure data, encrypts the customer bootstrap payload, and the browser passes the compact JWE to the SDK. Shared-secret mode authenticates the issuer by possession of the scoped channel secret and authenticates ciphertext integrity throughA256GCM. It does not use
a separate asymmetric customer signature.
Studio Setup
- Open the SDK channel in Studio.
- Set SDK auth mode to
hosted_exchange. - Enable customer-issued JWE.
- Set key mode to
shared_secret. - Set
maxAgeSecondsbetween60and900. Prefer300. - Choose whether to keep Runtime-issued Hosted Exchange bootstrap enabled:
acceptRuntimeIssued=trueallows the Runtime-signed/customer-sessionsflow to continue during migration.acceptRuntimeIssued=falselimits this channel to customer-issued JWE.
- Save the channel.
- Rotate the customer-issued JWE secret.
- Copy the one-time shared secret and
keyId. - Store the shared secret only in the customer backend secret manager.
Customer Server Changes
Install a JOSE implementation:customAttributes, not secureCustomData.
Customer-issued permission templates:
session:voice on a channel whose
public key has voice=false produces no voice grant. If the intersection is
empty, /api/v1/sdk/init returns a Hosted Exchange permissions error.
Browser SDK Changes
Use the same Hosted Exchange browser configuration as Runtime-signed bootstrap:apiKey, channelId, channelName, deploymentSlug,
userContext, or clientSessionIdentifier in this SDK config.
Validation
- Browser calls the customer backend bootstrap endpoint.
- Customer backend does not call
/api/v1/sdk/customer-sessions. - Browser passes the compact JWE to
/api/v1/sdk/initasbootstrapToken. - Runtime accepts the first use.
- Runtime rejects replay of the same
jti. - Runtime rejects expired tokens and tokens where
exp - iatexceeds channelmaxAgeSeconds. - Runtime rejects tokens with mismatched
tenantId,projectId,channelId,tid,pid, orcid. - Rotate the shared secret and confirm:
- In-flight tokens minted before rotation still work until expiry.
- Newly minted tokens using the old secret fail.
Scenario 4: Customer-Issued Public-Key JWE
This is the preferred no-new-Artemis-API-call option for higher-assurance flows. The customer backend signs the payload, encrypts it to Runtime, and the browser passes only the resulting compact JWE.Key Ownership
Studio Setup
- Generate a customer signing key pair in the customer environment.
- Copy only the customer signing public key.
- Open the SDK channel in Studio.
- Set SDK auth mode to
hosted_exchange. - Enable customer-issued JWE.
- Set key mode to
public_key. - Paste the PEM-encoded customer signing public key.
- Set
maxAgeSecondsbetween60and900. Prefer300. - Choose whether
acceptRuntimeIssuedshould remain enabled for migration. - Save the channel.
- Rotate the customer-issued JWE key.
- Copy the Runtime channel public encryption key and
keyId. - Store the Runtime public encryption key and
keyIdin customer backend configuration.
customer-signing-public.pem to Studio. Store
customer-signing-private.pem only in the customer backend secret manager or
HSM. The TypeScript example below expects the private key in PKCS#8 PEM format
and the public key in SPKI PEM format.
Customer-issued public-key JWE config shape:
Customer Server Changes
Install a JOSE implementation:Browser SDK Changes
Use the same Hosted Exchange browser configuration:Validation
- Customer backend does not call
/api/v1/sdk/customer-sessions. - Browser passes compact JWE to
/api/v1/sdk/initasbootstrapToken. - Runtime decrypts the JWE and verifies the inner JWS.
- Runtime rejects an unsigned plaintext payload in public-key mode.
- Runtime rejects wrong
ctyvalues such asapplication/jsonin public-key mode. - Runtime rejects tokens signed by an unconfigured customer private key.
- Runtime rejects replay, scope drift, expired tokens, overlong tokens, and disabled-channel tokens.
- Rotate the Runtime channel public encryption key and confirm:
- In-flight tokens minted before rotation still work until expiry.
- Newly minted tokens using the retired key fail.
Studio Operations Checklist
For public anonymous SDK:- SDK channel auth mode is
anonymous. - Allowed origins include the browser site.
- Public API key is active and scoped to the project.
- Channel is active and bound to the expected deployment/environment.
- SDK channel auth mode is
hosted_exchange. - Server secret exists and is stored by the customer backend.
sdkTokenEnvelopePolicyis selected intentionally.- Runtime capability is ready before selecting
jwe_required. - Customer-issued JWE may remain disabled.
- SDK channel auth mode is
hosted_exchange. customerIssuedJwe.enabled=true.customerIssuedJwe.keyMode=shared_secret.customerIssuedJwe.maxAgeSecondsmatches the customer backend token TTL.- Secret has been rotated and copied once to the customer backend.
acceptRuntimeIssuedmatches the migration plan.
- SDK channel auth mode is
hosted_exchange. customerIssuedJwe.enabled=true.customerIssuedJwe.keyMode=public_key.- Customer signing public key is configured.
- Runtime public encryption key has been rotated and copied to the customer backend.
customerIssuedJwe.maxAgeSecondsmatches the customer backend token TTL.acceptRuntimeIssuedmatches the migration plan.
Studio API Automation Payloads
Use these shapes when automating setup through Studio instead of clicking through the channel configuration UI. Create a Hosted Exchange channel:customerIssuedJweSecret.secret is returned once in the
same response. Store it immediately in the customer backend secret manager. It
will not be available from later safe metadata reads.
Customer Backend Checklist
All Hosted Exchange customer backend endpoints should:- Require the customer application’s own authenticated session.
- Derive
verifiedUserIdserver-side. - Fetch sensitive or secure attributes server-side.
- Put secure attributes under
customAttributes. - Generate unique
jtivalues. - Use short TTLs. Prefer 5 minutes or less.
- Avoid logging bootstrap tokens, secure attributes, sensitive data, server secrets, or private keys.
- Return only
{ "bootstrapToken": "..." }and optional non-sensitive expiry metadata to the browser. - Rate limit token minting per customer session.
- Alert on repeated invalid token minting, Runtime 401s, and replay failures.
Browser SDK Checklist
For public anonymous SDK:- Use
apiKey. - Optional:
channelId,channelName,deploymentSlug,userContext,clientSessionIdentifier.
- Use
bootstrapTokenProviderwhen possible. - Do not combine Hosted Exchange bootstrap config with
apiKey. - Do not pass browser
userContext; put verified data in the backend token. - Do not pass
channelId,channelName, ordeploymentSlug; Runtime resolves those from the bootstrap token. projectIdis still required for bootstrap-token configs.sessionMetadatais allowed, but it is not identity. Use it for safe browser context such as locale, timezone, or UI context.- Make the bootstrap provider call same-origin or protected by customer auth.
- Handle bootstrap failure as an auth/session startup failure, not as a bot error.
Manual Runtime Probes
Use these probes after Studio and customer backend setup. Replace placeholders with environment-specific values and do not paste real secrets into tickets, logs, or shared terminals. Public anonymous SDK init:Deployment Checklist
Runtime:- Configure
JWT_SECRET. - Configure
AUTH_SDK_BOOTSTRAP_SIGNING_SECRET. - Configure
AUTH_SDK_SESSION_SIGNING_SECRET. - Configure
ENCRYPTION_MASTER_KEYfor JWE envelope support. - Keep
AUTH_SDK_JWE_ENABLEDunset ortruefor JWE rollout. - Configure
REDIS_URLfor tickets, replay protection, and distributed state. - Expose Runtime over HTTPS.
- Verify
/api/projects/:projectId/sdk-jwe-capabilitybefore enforcing JWE. - Deploy all Runtime pods with the same auth and encryption settings.
- Studio must reach Runtime for channel mutation APIs and JWE capability preflight.
- Studio users need channel permissions to create/update SDK channel auth settings.
- Treat one-time revealed secrets as unrecoverable; rotate if they are missed or exposed.
- Store Runtime endpoint, tenant ID, project ID, and channel ID as deploy config.
- Store scenario-specific secrets in a secret manager or HSM.
- Rotate secrets through Studio first, then update customer backend config.
- Deploy customer backend before switching the browser SDK to Hosted Exchange bootstrap.
- Use HTTPS and secure cookies for the browser-to-customer bootstrap endpoint.
- Serve an SDK bundle version that supports
bootstrapTokenProviderand WebSocketsdk-ticket. - Set Runtime endpoint and project ID per environment.
- Keep Hosted Exchange bootstrap calls credentialed when the customer session uses cookies.
- Do not persist bootstrap tokens in local storage.
End-To-End Cutover Plan
- Create or update the SDK channel in Studio.
- Set allowed origins and deployment binding.
- For Hosted Exchange, configure channel auth mode and token/JWE settings.
- Deploy Runtime with required auth, Redis, and encryption configuration.
- Verify Runtime JWE capability if
jwe_preferredorjwe_requiredis used. - Deploy the customer backend bootstrap endpoint.
- Validate the backend endpoint with a real customer session.
- Deploy browser SDK changes.
- Start with an internal or allowlisted origin.
- Exercise init, refresh, chat send, attachment if used, WebSocket ticket, and WebSocket connect.
- Check Runtime logs and audit events for invalid token, replay, origin, or scope failures.
- For migration channels, keep
acceptRuntimeIssued=trueuntil all browser and customer backend clients are using customer-issued JWE. - When ready, set
acceptRuntimeIssued=falsefor customer-issued-only channels, or setsdkTokenEnvelopePolicy=jwe_requiredfor Runtime-issued Hosted Exchange channels.
Expanded Scenario Coverage Matrix
Use this matrix for implementation review, QA planning, and customer security approval. A complete rollout should cover the positive path and at least the listed negative path for each scenario in the target environment.
Minimum evidence for each selected production scenario:
- Studio screenshot or API response showing channel auth mode, token envelope policy, customer JWE mode, and active key metadata.
- Customer backend request/response trace with secrets and sensitive data redacted.
- Runtime init response showing
channelId,permissions,tokenEnvelopewhen present, andexpiresIn. - SDK browser trace showing no channel secret, customer JWE secret, Runtime private key, or customer signing private key is present client-side.
- WebSocket ticket response and successful WebSocket connection using
sdk-ticket. - Negative-path evidence for replay, origin, expiry, and key-mode mismatch for customer-issued JWE scenarios.