Skip to main content
Back to SDKs Overview The Agent Platform SDK is a TypeScript/JavaScript library for embedding agent chat and voice interactions in web applications. It supports vanilla JavaScript, React hooks, and a web component for drop-in integration. For the full SDK reference, see the SDKs Overview. This guide explains how to configure Artemis SDK authentication end to end across Studio, the browser SDK, the customer backend, and deployment/runtime settings. It covers these scenarios:
  1. Public anonymous SDK
  2. Runtime-signed Hosted Exchange bootstrap
  3. Customer-issued shared-secret JWE
  4. 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-256 and A256GCM.
  • The inner JWS gives issuer authentication using the customer signing private key and Runtime-configured customer signing public key.
Do not treat public-key encryption alone as issuer authentication.

Shared Runtime Flow After Bootstrap

All four scenarios converge after browser initialization:

Permission And Origin Resolution

Public API key permissions are stored as coarse chat 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_message
  • session:voice
  • session:read
  • attachment:read
  • attachment:write
  • attachment:delete
Origin enforcement happens after Runtime resolves the channel:
  • 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

  1. Create or select the project that owns the SDK channel.
  2. Create or select the deployment the SDK channel should route to.
  3. Create or select a public SDK API key for the project.
  4. 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.
  5. Create an SDK channel and bind it to the deployment or environment.
  6. Keep the channel active only after customer backend and browser changes are deployed.
The Studio channel auth mode decides the setup path:
  • anonymous for public anonymous SDK.
  • hosted_exchange for 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, and AUTH_SDK_SESSION_SIGNING_SECRET configured consistently across Runtime pods.
  • ENCRYPTION_MASTER_KEY configured when Hosted Exchange token envelope JWE is required or preferred.
  • AUTH_SDK_JWE_ENABLED unset or true when JWE issuance/verification should be available.
  • REDIS_URL configured 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.
Before enabling strict Hosted Exchange JWE, verify capability:
Expected ready response:
If 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

  1. Open the project deployment channel settings in Studio.
  2. Create or edit an SDK channel.
  3. Set SDK auth mode to anonymous.
  4. Bind the channel to the target deployment or environment.
  5. Configure allowed origins for the browser site.
  6. Save the channel.
  7. Copy the public SDK API key and channel identifier or channel name.
Do not configure 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
Do not put channel server secrets, customer JWE secrets, Runtime private keys, or customer signing private keys in browser-rendered HTML or JavaScript.

Browser SDK Changes

Core SDK:
Public-key variants:
React:
Custom element:

Validation

  1. Load the browser site from an allowed origin.
  2. Confirm /api/v1/sdk/init uses X-Public-Key.
  3. Confirm the request body does not include bootstrapToken.
  4. Send a chat message.
  5. Confirm /api/v1/sdk/ws-ticket succeeds before WebSocket connect.
  6. 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

  1. Open the project deployment channel settings in Studio.
  2. Create or edit an SDK channel.
  3. Set SDK auth mode to hosted_exchange.
  4. Configure allowed origins.
  5. Select sdkTokenEnvelopePolicy:
    • signed for signed-token compatibility.
    • jwe_preferred for rollout where JWE is used when Runtime capability is ready.
    • jwe_required after the capability endpoint shows Runtime can issue and verify JWE.
  6. Save the channel.
  7. Copy the Hosted Exchange server secret when Studio reveals it.
  8. 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:
Request body rules:
  • Send exactly one of channelId or channelName.
  • Do not send permissions; Runtime derives the effective SDK permissions from the channel’s active public API key.
  • Keep customAttributes within the SDK user context size limits. Runtime returns SDK_TOKEN_TOO_LARGE when normalized custom attributes exceed the token budget.
channelName variant:
Successful Runtime response:
When 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 verifiedUserId stable 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 a bootstrapTokenProvider so each fresh init gets a new short-lived token:
React:
Custom element:
Set the bootstrapTokenProvider property before appending the custom element. The widget reads SDK config during its connection/bootstrap lifecycle.

Validation

  1. Customer backend calls POST /api/v1/sdk/customer-sessions.
  2. Browser calls /api/v1/sdk/init with bootstrapToken and without X-Public-Key.
  3. Runtime returns an SDK session token.
  4. If sdkTokenEnvelopePolicy=jwe_required, confirm returned Hosted Exchange bootstrap/session material is JWE or the flow fails closed.
  5. Replay the same bootstrap token and confirm Runtime rejects it.
  6. 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 through A256GCM. It does not use a separate asymmetric customer signature.

Studio Setup

  1. Open the SDK channel in Studio.
  2. Set SDK auth mode to hosted_exchange.
  3. Enable customer-issued JWE.
  4. Set key mode to shared_secret.
  5. Set maxAgeSeconds between 60 and 900. Prefer 300.
  6. Choose whether to keep Runtime-issued Hosted Exchange bootstrap enabled:
    • acceptRuntimeIssued=true allows the Runtime-signed /customer-sessions flow to continue during migration.
    • acceptRuntimeIssued=false limits this channel to customer-issued JWE.
  7. Save the channel.
  8. Rotate the customer-issued JWE secret.
  9. Copy the one-time shared secret and keyId.
  10. Store the shared secret only in the customer backend secret manager.
Customer-issued JWE config shape:

Customer Server Changes

Install a JOSE implementation:
Mint the compact JWE server-side:
Expose it through a customer backend endpoint:
Required JWE header fields:
Required payload fields:
Runtime rejects unsupported top-level claims. Put secure custom data in customAttributes, not secureCustomData. Customer-issued permission templates:
Runtime intersects these requested permissions with the channel’s bound public API key permissions. For example, requesting 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:
Do not pass apiKey, channelId, channelName, deploymentSlug, userContext, or clientSessionIdentifier in this SDK config.

Validation

  1. Browser calls the customer backend bootstrap endpoint.
  2. Customer backend does not call /api/v1/sdk/customer-sessions.
  3. Browser passes the compact JWE to /api/v1/sdk/init as bootstrapToken.
  4. Runtime accepts the first use.
  5. Runtime rejects replay of the same jti.
  6. Runtime rejects expired tokens and tokens where exp - iat exceeds channel maxAgeSeconds.
  7. Runtime rejects tokens with mismatched tenantId, projectId, channelId, tid, pid, or cid.
  8. 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

  1. Generate a customer signing key pair in the customer environment.
  2. Copy only the customer signing public key.
  3. Open the SDK channel in Studio.
  4. Set SDK auth mode to hosted_exchange.
  5. Enable customer-issued JWE.
  6. Set key mode to public_key.
  7. Paste the PEM-encoded customer signing public key.
  8. Set maxAgeSeconds between 60 and 900. Prefer 300.
  9. Choose whether acceptRuntimeIssued should remain enabled for migration.
  10. Save the channel.
  11. Rotate the customer-issued JWE key.
  12. Copy the Runtime channel public encryption key and keyId.
  13. Store the Runtime public encryption key and keyId in customer backend configuration.
Example customer signing key generation:
Upload 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:
Mint the signed-then-encrypted bootstrap token:
Expose it through a customer backend endpoint:
Required outer JWE header fields:
Required inner JWS header fields:
The inner JWS payload uses the same claim shape as shared-secret mode.

Browser SDK Changes

Use the same Hosted Exchange browser configuration:

Validation

  1. Customer backend does not call /api/v1/sdk/customer-sessions.
  2. Browser passes compact JWE to /api/v1/sdk/init as bootstrapToken.
  3. Runtime decrypts the JWE and verifies the inner JWS.
  4. Runtime rejects an unsigned plaintext payload in public-key mode.
  5. Runtime rejects wrong cty values such as application/json in public-key mode.
  6. Runtime rejects tokens signed by an unconfigured customer private key.
  7. Runtime rejects replay, scope drift, expired tokens, overlong tokens, and disabled-channel tokens.
  8. 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:
  1. SDK channel auth mode is anonymous.
  2. Allowed origins include the browser site.
  3. Public API key is active and scoped to the project.
  4. Channel is active and bound to the expected deployment/environment.
For Runtime-signed Hosted Exchange:
  1. SDK channel auth mode is hosted_exchange.
  2. Server secret exists and is stored by the customer backend.
  3. sdkTokenEnvelopePolicy is selected intentionally.
  4. Runtime capability is ready before selecting jwe_required.
  5. Customer-issued JWE may remain disabled.
For customer-issued shared-secret JWE:
  1. SDK channel auth mode is hosted_exchange.
  2. customerIssuedJwe.enabled=true.
  3. customerIssuedJwe.keyMode=shared_secret.
  4. customerIssuedJwe.maxAgeSeconds matches the customer backend token TTL.
  5. Secret has been rotated and copied once to the customer backend.
  6. acceptRuntimeIssued matches the migration plan.
For customer-issued public-key JWE:
  1. SDK channel auth mode is hosted_exchange.
  2. customerIssuedJwe.enabled=true.
  3. customerIssuedJwe.keyMode=public_key.
  4. Customer signing public key is configured.
  5. Runtime public encryption key has been rotated and copied to the customer backend.
  6. customerIssuedJwe.maxAgeSeconds matches the customer backend token TTL.
  7. acceptRuntimeIssued matches 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:
Enable customer-issued public-key JWE on an existing channel:
Enable customer-issued shared-secret JWE:
Rotation response material:
For shared-secret mode, 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:
  1. Require the customer application’s own authenticated session.
  2. Derive verifiedUserId server-side.
  3. Fetch sensitive or secure attributes server-side.
  4. Put secure attributes under customAttributes.
  5. Generate unique jti values.
  6. Use short TTLs. Prefer 5 minutes or less.
  7. Avoid logging bootstrap tokens, secure attributes, sensitive data, server secrets, or private keys.
  8. Return only { "bootstrapToken": "..." } and optional non-sensitive expiry metadata to the browser.
  9. Rate limit token minting per customer session.
  10. Alert on repeated invalid token minting, Runtime 401s, and replay failures.
Required customer backend material by scenario:

Browser SDK Checklist

For public anonymous SDK:
  • Use apiKey.
  • Optional: channelId, channelName, deploymentSlug, userContext, clientSessionIdentifier.
For all Hosted Exchange scenarios:
  • Use bootstrapTokenProvider when 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, or deploymentSlug; Runtime resolves those from the bootstrap token.
  • projectId is still required for bootstrap-token configs.
  • sessionMetadata is 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:
Runtime-signed Hosted Exchange bootstrap mint:
Hosted Exchange bootstrap exchange, for Runtime-signed and customer-issued JWE:
WebSocket ticket mint from the SDK session token returned by init:
Negative probes worth running:

Deployment Checklist

Runtime:
  1. Configure JWT_SECRET.
  2. Configure AUTH_SDK_BOOTSTRAP_SIGNING_SECRET.
  3. Configure AUTH_SDK_SESSION_SIGNING_SECRET.
  4. Configure ENCRYPTION_MASTER_KEY for JWE envelope support.
  5. Keep AUTH_SDK_JWE_ENABLED unset or true for JWE rollout.
  6. Configure REDIS_URL for tickets, replay protection, and distributed state.
  7. Expose Runtime over HTTPS.
  8. Verify /api/projects/:projectId/sdk-jwe-capability before enforcing JWE.
  9. Deploy all Runtime pods with the same auth and encryption settings.
Studio:
  1. Studio must reach Runtime for channel mutation APIs and JWE capability preflight.
  2. Studio users need channel permissions to create/update SDK channel auth settings.
  3. Treat one-time revealed secrets as unrecoverable; rotate if they are missed or exposed.
Customer backend:
  1. Store Runtime endpoint, tenant ID, project ID, and channel ID as deploy config.
  2. Store scenario-specific secrets in a secret manager or HSM.
  3. Rotate secrets through Studio first, then update customer backend config.
  4. Deploy customer backend before switching the browser SDK to Hosted Exchange bootstrap.
  5. Use HTTPS and secure cookies for the browser-to-customer bootstrap endpoint.
Browser app:
  1. Serve an SDK bundle version that supports bootstrapTokenProvider and WebSocket sdk-ticket.
  2. Set Runtime endpoint and project ID per environment.
  3. Keep Hosted Exchange bootstrap calls credentialed when the customer session uses cookies.
  4. Do not persist bootstrap tokens in local storage.

End-To-End Cutover Plan

  1. Create or update the SDK channel in Studio.
  2. Set allowed origins and deployment binding.
  3. For Hosted Exchange, configure channel auth mode and token/JWE settings.
  4. Deploy Runtime with required auth, Redis, and encryption configuration.
  5. Verify Runtime JWE capability if jwe_preferred or jwe_required is used.
  6. Deploy the customer backend bootstrap endpoint.
  7. Validate the backend endpoint with a real customer session.
  8. Deploy browser SDK changes.
  9. Start with an internal or allowlisted origin.
  10. Exercise init, refresh, chat send, attachment if used, WebSocket ticket, and WebSocket connect.
  11. Check Runtime logs and audit events for invalid token, replay, origin, or scope failures.
  12. For migration channels, keep acceptRuntimeIssued=true until all browser and customer backend clients are using customer-issued JWE.
  13. When ready, set acceptRuntimeIssued=false for customer-issued-only channels, or set sdkTokenEnvelopePolicy=jwe_required for 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:
  1. Studio screenshot or API response showing channel auth mode, token envelope policy, customer JWE mode, and active key metadata.
  2. Customer backend request/response trace with secrets and sensitive data redacted.
  3. Runtime init response showing channelId, permissions, tokenEnvelope when present, and expiresIn.
  4. SDK browser trace showing no channel secret, customer JWE secret, Runtime private key, or customer signing private key is present client-side.
  5. WebSocket ticket response and successful WebSocket connection using sdk-ticket.
  6. Negative-path evidence for replay, origin, expiry, and key-mode mismatch for customer-issued JWE scenarios.

Troubleshooting