Skip to content

JWT authentication

Open in ChatGPT Open in Claude

JWT authentication ties every agent request to a backend-verified user identity. Use it on any production deployment so a user can only access their own conversations, history, and actions, and so requests can’t be forged from the client.

Without authentication, a malicious actor could impersonate a user, read private conversations, or invoke actions on their behalf. JWT authentication guarantees:

  • A user can only access their own conversations and data.
  • Requests to the agent can’t be forged from the client side.
  • Conversation history and agent actions are protected from identity theft.

A JSON Web Token (JWT) is a compact, signed token used to transmit identity information between systems. A JWT:

  • Is generated by a trusted backend.
  • Is cryptographically signed with a secret key.
  • Can be verified by a server without additional database lookups.
  • Has a built-in expiration time.

In Foldspace, the JWT acts as proof of identity for the user interacting with the agent. Requiring a server-signed token means user identity can’t be spoofed, only authenticated users can send messages or retrieve conversations, and tokens expire automatically to limit exposure if compromised.

  1. You generate a secret key in the Foldspace dashboard.
  2. Your backend uses the secret to sign a JWT with HS256.
  3. The signed JWT is sent to the browser.
  4. The Foldspace Web SDK includes the JWT in every request.
  5. Foldspace verifies the token and user identity on every call.
sequenceDiagram
  participant B as Your Backend
  participant C as Browser
  participant S as Foldspace SDK
  participant F as Foldspace
  B->>B: Sign JWT (HS256) with secret key
  B->>C: Return signed JWT
  C->>S: Initialize with token
  S->>F: Request + JWT header
  F->>F: Verify signature & expiry
  F-->>S: Authenticated response
  Note over S,F: On expiry, SDK calls onTokenExpired
  S->>C: Request fresh token
  C->>B: Fetch new JWT
  B->>C: New signed JWT
  C->>S: Return token

JWT signing keys are managed under Settings → Identity Verification. You can generate one or more JWT secret keys.

  • These keys sign JWTs in your backend.
  • They must be kept private and secure.
  • They must never be exposed in frontend code.

Once generated, copy the secret key and store it securely, for example, as an environment variable.

To copy a secret key or change a key’s status, a Foldspace user must have the Jwt Settings Admin role. Users without this role can view configuration but can’t access or modify secret keys.

Foldspace supports key rotation so you can maintain security without service disruption. You manage rotation, and multiple secret keys can coexist for safe transitions in production.

Each secret key has a status that controls how it’s enforced.

StatusEnforcementNotes
INACTIVENot enforcedDefault status when a key is created. The key can be copied and safely prepared for deployment. Can be moved to INACTIVE from any status except REVOKED.
ACTIVEFully enforcedTokens signed with this key are accepted by Foldspace.
TESTINGEvaluated, not enforcedValidates JWT signing without enforcing authentication. Only one TESTING key is allowed at a time. Verification results are returned in a response header. Does not affect production traffic or agent availability.
DEPRECATEDValid and enforcedUsed during key rotation. Lets existing backend deployments keep working while a new key is rolled out.
REVOKEDRejectedPermanently disabled and deleted. Tokens signed with this key are rejected. Status can’t be changed once revoked.
  1. Create a new secret key (initially INACTIVE).
  2. Deploy the new key to your backend.
  3. Move the new key to ACTIVE.
  4. Move the old key to DEPRECATED.
  5. Once fully migrated, move the deprecated key to REVOKED.

This rotates keys with no downtime.

stateDiagram-v2
  [*] --> INACTIVE: Key created
  INACTIVE --> ACTIVE: Deploy & activate
  INACTIVE --> TESTING: Validate first
  TESTING --> ACTIVE: Promote
  ACTIVE --> DEPRECATED: New key activated
  DEPRECATED --> REVOKED: Migration complete
  REVOKED --> [*]
  note right of TESTING: One TESTING key at a time.<br/>Not enforced — result in header.
  note right of DEPRECATED: Still accepted.<br/>Gives backends time to migrate.

Create the JWT only in your backend and sign it with the HS256 algorithm. Tokens signed with any other algorithm are rejected.

{
"userId": "<the same user ID you pass to the Foldspace JS SDK>",
"exp": <expiration time in seconds since epoch>
}
RequirementValue
AlgorithmHS256
SecretACTIVE or DEPRECATED Foldspace secret key
LocationBackend only
import jwt from "jsonwebtoken";
const FOLDSPACE_SECRET = process.env.FOLDSPACE_JWT_SECRET;
function generateFoldspaceToken(userId) {
const expiresInSeconds =
Math.floor(Date.now() / 1000) + (15 * 60);
return jwt.sign(
{ userId, exp: expiresInSeconds },
FOLDSPACE_SECRET,
{ algorithm: "HS256" }
);
}

Provide the signed JWT to the Foldspace Web SDK through the agent API:

// 1. Fetch the token from your backend API
const response = await fetch('/api/auth/foldspace-token');
const { token } = await response.json();
// 2. Initialize Foldspace agent via the agent API
const agent = foldspace.agent({
apiName: 'the-agent-api-name',
token: token,
onTokenExpired: async () => {
const response = await fetch('/api/auth/foldspace-token');
const { token } = await response.json();
console.log('token refreshed', token);
return token;
}
});
agent.show();

Here, the frontend fetches a signed JWT from your backend and passes it via the token property. The SDK attaches the token to every request. When the token expires, the SDK calls onTokenExpired, and your UI fetches and returns a new token.

Use a TESTING key to validate JWT signing before you enforce authentication in production.

  1. Move a secret key to TESTING (only one key can be in TESTING at a time).
  2. Sign a JWT with the TESTING key.
  3. Send requests using that JWT via the Foldspace SDK.
  4. Foldspace evaluates the token and returns the result in a response header.

For requests signed with a TESTING key, Foldspace returns the verification result in this header:

Header
X-Jwt-Testing-Result
ValueMeaning
validatedThe JWT is correctly signed and structured.
failedThe JWT is invalid, expired, or incorrectly signed.

This lets you verify signature correctness, payload structure, and expiration handling without impacting production users.

Use a TESTING key when you want to validate a new backend JWT implementation, confirm the signing algorithm (HS256), verify payload structure and expiration handling, or test new keys before promoting them to ACTIVE.

  • Use short-lived tokens (5–30 minutes).
  • Refresh tokens from your backend when needed.

Short expiration times reduce risk and align with modern security standards.

Token expired. The SDK invokes onTokenExpired. Fetch a new JWT with a fresh exp from your backend and return it to the SDK.

Invalid token. If the token is invalid or can’t be verified, all agent requests are rejected, the agent is automatically hidden from the UI, and user data and actions remain protected.