Tokens
Apps can be shared externally via tokens, allowing access without a full Informer account. Tokens provide read-only access and are managed through the Token API.
Token Types
Apps use the app-view token type, which:
- Grants read-only access to the app
- Requires an
appIdfield - Can be used to access
/api/apps/{id}/viewendpoints - Cannot be used for write operations
GET /api/apps/{id}/tokens
Get all tokens associated with an app.
Authentication: Required
Permissions Required: None (any user who can read the app)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
Returns a HAL collection of Token records.
{
"_links": {
"self": { "href": "/api/apps/analytics:sales-dashboard/tokens" }
},
"_embedded": {
"inf:app-token": [
{
"_links": {
"self": { "href": "/api/tokens/token-uuid-1" }
},
"id": "token-uuid-1",
"type": "app-view",
"appId": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"name": "Public Dashboard Link",
"token": "abc123def456...",
"readOnly": true,
"createdAt": "2024-02-10T10:00:00.000Z",
"expiresAt": null
}
]
},
"tokens": [...]
}
Key Fields:
| Field | Description |
|---|---|
id | Token UUID |
type | Always "app-view" for app tokens |
appId | Associated app UUID |
name | Optional display name |
token | The actual token string (use for authentication) |
readOnly | Always true for app-view tokens |
expiresAt | Expiration date (null = never expires) |
Error Responses:
404 Not Found- App doesn't exist or user lacks access
Creating App Tokens
Tokens are created through the general Token API (POST /api/tokens), not through the app-specific endpoint.
Example: Create an App Token
POST /api/tokens
Content-Type: application/json
{
"type": "app-view",
"appId": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"name": "Public Dashboard Link",
"expiresAt": "2025-12-31T23:59:59.000Z"
}
Response:
{
"id": "token-uuid-1",
"type": "app-view",
"appId": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"name": "Public Dashboard Link",
"token": "abc123def456ghi789...",
"readOnly": true,
"createdAt": "2024-02-13T10:30:00.000Z",
"expiresAt": "2025-12-31T23:59:59.000Z"
}
Required Fields:
| Field | Type | Description |
|---|---|---|
type | string | Must be "app-view" |
appId | string | App UUID |
Optional Fields:
| Field | Type | Description |
|---|---|---|
name | string | Display name for the token |
expiresAt | string | ISO 8601 date (null = never expires) |
Using App Tokens
Once a token is created, it can be used to access the app without authentication.
Token Authentication
Include the token in requests using the Authorization header:
GET /api/apps/d4f8a2b1-1234-5678-90ab-cdef12345678/view
Authorization: Bearer abc123def456ghi789...
View Endpoint Access
App-view tokens grant access to:
GET /api/apps/{id}/view- App entry point (HTML)GET /api/apps/{id}/view/-/{path*}- Static assets (CSS, JS, images)GET /api/apps/{id}/view/api/{path*}- Proxied API calls (subject to whitelist)GET /api/apps/{id}/contents/{path*}- Read app files
Restrictions:
- Read-Only: Tokens cannot be used to modify the app or its data
- No Write Operations: PUT, POST, PATCH, DELETE are not allowed
- Whitelist Enforcement: API proxy calls are subject to the app's data access whitelist
- App-Specific: Token only works for the specified
appId
Revoking Tokens
Tokens are revoked through the general Token API.
Example: Revoke a Token
DELETE /api/tokens/token-uuid-1
Response:
Returns 204 No Content on success.
Effect:
- Token immediately becomes invalid
- Any in-progress requests using the token may fail
- The token string can no longer be used for authentication
Common Token Workflows
Create a Public Dashboard Link
// 1. Create a token for the app
const token = await POST('/api/tokens', {
type: 'app-view',
appId: 'analytics:sales-dashboard',
name: 'Public Dashboard - Q1 2024',
expiresAt: '2024-04-01T00:00:00.000Z'
});
// 2. Construct the shareable URL
const dashboardURL = `https://your-informer.com/api/apps/${appId}/view?token=${token.token}`;
console.log('Share this URL:', dashboardURL);
List All Tokens for an App
const response = await GET('/api/apps/analytics:sales-dashboard/tokens');
console.log(`Found ${response.tokens.length} tokens:`);
for (const token of response.tokens) {
console.log(`- ${token.name || 'Unnamed'} (expires: ${token.expiresAt || 'never'})`);
}
Revoke Expired Tokens
// Get all tokens for the app
const response = await GET('/api/apps/analytics:sales-dashboard/tokens');
const now = new Date();
// Find expired tokens
const expiredTokens = response.tokens.filter(t =>
t.expiresAt && new Date(t.expiresAt) < now
);
// Revoke them
for (const token of expiredTokens) {
await DELETE(`/api/tokens/${token.id}`);
console.log(`Revoked expired token: ${token.name || token.id}`);
}
Create a Time-Limited Demo Link
// Create a token that expires in 7 days
const expiresAt = new Date();
expiresAt.setDate(expiresAt.getDate() + 7);
const token = await POST('/api/tokens', {
type: 'app-view',
appId: 'analytics:sales-dashboard',
name: 'Demo Link - Week of Feb 13',
expiresAt: expiresAt.toISOString()
});
console.log('Demo link:', `${baseURL}/api/apps/${appId}/view?token=${token.token}`);
console.log('Expires:', expiresAt.toLocaleDateString());
Rotate Tokens
// Get existing token
const response = await GET('/api/apps/analytics:sales-dashboard/tokens');
const oldToken = response.tokens.find(t => t.name === 'Public Dashboard');
// Create new token with same settings
const newToken = await POST('/api/tokens', {
type: 'app-view',
appId: 'analytics:sales-dashboard',
name: 'Public Dashboard',
expiresAt: oldToken.expiresAt
});
// Revoke old token
if (oldToken) {
await DELETE(`/api/tokens/${oldToken.id}`);
}
console.log('New token:', newToken.token);
Security Considerations
Token Visibility
- Tokens are visible to anyone who can read the app
- The token string itself provides access, so treat it as a password
- Anyone with the token can access the app (until expiration or revocation)
Best Practices
- Use Expiration: Always set
expiresAtfor public tokens - Name Tokens: Use descriptive names to track usage
- Rotate Regularly: Change tokens periodically for public apps
- Monitor Usage: Check the tokens list regularly and revoke unused ones
- Limit Scope: Create separate tokens for different use cases
Token Validation
The app-view token driver enforces:
appIdmust be presentreadOnlyis always set totrue- Token is only valid for the specified app
API Proxy Whitelist
Even with a valid token, API calls through /api/apps/{id}/view/api/ are subject to the app's data access whitelist. This prevents malicious apps from accessing arbitrary data.
Token Lifecycle
- Creation: Token is created via
POST /api/tokens - Active: Token can be used to access the app
- Expiration: If
expiresAtis set, token becomes invalid at that time - Revocation: Token is deleted via
DELETE /api/tokens/{id} - Cleanup: Expired tokens should be periodically cleaned up
Related Endpoints
POST /api/tokens- Create tokensGET /api/tokens/{id}- Get token detailsDELETE /api/tokens/{id}- Revoke tokensGET /api/tokens- List all tokens (admin)