Selegic CRM Docs
ServerExtensions

Token Security

Cross-domain authentication for extensions using JWTs.

Extensions run in iframes on different domains than the Selegic API. Short-lived JWTs (Extension Tokens) enable secure communication.

Token Anatomy

Extension tokens are JWTs signed with EXTENSION_TOKEN_SECRET:

interface ExtensionTokenPayload {
  orgId: string;
  userId: string;
  extension_id: string;
  scopes: string[]; // e.g., ["actions:invoke", "records:read:contact"]
}
PropertyValue
Lifetime1 hour (configurable)
AlgorithmHS256 (symmetric)
AudienceExtension ID

Token Flow

generateExtensionToken() pass token in iframe src Authorization: Bearer <token> verifyExtensionToken() action response Selegic Web Extension iframe CRM API

Steps

  1. Generation: Web app calls generateExtensionToken() before loading iframe
  2. Injection: Token passed via iframe URL parameter
  3. Invocation: Extension includes token in Authorization header
  4. Verification: Server validates signature, expiry, populates ActionContext

Generation

import { generateExtensionToken } from "@/features/extensions/helpers/token-helpers";

const token = await generateExtensionToken({
  orgId: "org_123",
  userId: "user_456",
  extensionId: "ext_789",
  scopes: ["actions:invoke", "records:read:contact"],
});

Verification

import { verifyExtensionToken } from "@/features/extensions/helpers/token-helpers";

const payload = await verifyExtensionToken(token);
// Returns ExtensionTokenPayload

Security Best Practices

1. Secret Rotation

Rotate EXTENSION_TOKEN_SECRET periodically:

# In production, use secret manager rotation
# If compromised, regenerate immediately

2. Minimal Scopes

Grant least-privilege permissions:

// Good: specific scopes
scopes: ["actions:find_many", "records:read:contact"]

// Avoid: wildcards
scopes: ["*"]  // Never do this

3. Short TTL

Default 1 hour balances usability and security:

  • Too short: Poor UX (frequent re-auth)
  • Too long: Larger attack window

Troubleshooting

ErrorCauseResolution
Signature InvalidSecret mismatchVerify EXTENSION_TOKEN_SECRET matches
Token ExpiredTTL exceededRequest new token
Invalid AudienceWrong extensionVerify extension ID in token
No Active InstallationExtension not installedInstall extension for org

On this page