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"]
}| Property | Value |
|---|---|
| Lifetime | 1 hour (configurable) |
| Algorithm | HS256 (symmetric) |
| Audience | Extension ID |
Token Flow
Steps
- Generation: Web app calls
generateExtensionToken()before loading iframe - Injection: Token passed via iframe URL parameter
- Invocation: Extension includes token in
Authorizationheader - 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 ExtensionTokenPayloadSecurity Best Practices
1. Secret Rotation
Rotate EXTENSION_TOKEN_SECRET periodically:
# In production, use secret manager rotation
# If compromised, regenerate immediately2. Minimal Scopes
Grant least-privilege permissions:
// Good: specific scopes
scopes: ["actions:find_many", "records:read:contact"]
// Avoid: wildcards
scopes: ["*"] // Never do this3. Short TTL
Default 1 hour balances usability and security:
- Too short: Poor UX (frequent re-auth)
- Too long: Larger attack window
Troubleshooting
| Error | Cause | Resolution |
|---|---|---|
Signature Invalid | Secret mismatch | Verify EXTENSION_TOKEN_SECRET matches |
Token Expired | TTL exceeded | Request new token |
Invalid Audience | Wrong extension | Verify extension ID in token |
No Active Installation | Extension not installed | Install extension for org |