Authentication
Manager supports multiple authentication methods for different use cases.
Authentication Methods
Personal Access Tokens (PAT)
For user-driven API access.
Use cases:
- CLI tools
- Scripts
- Third-party integrations
- Development/testing
Security: PBKDF2 with 600,000 iterations (OWASP 2023)
Machine Users
For service-to-service authentication.
Use cases:
- Backend services
- Automated workflows
- Trigger execution
- System integrations
Methods: Bearer token OR Basic auth
Personal Access Tokens
Creating a PAT
- Navigate to Personal Access Tokens in sidebar
- Click Create Token
- Enter Token Name (e.g., "CLI Access")
- Optional: Set Expiration Date
- Click Create
- Copy the token - shown only once!
Using a PAT
Include in HTTP headers:
bash
curl -H "Authorization: Bearer pfy_abc123..." \
https://manager.example.com/graphqlWith GraphQL client:
typescript
const client = createClient({
url: "https://manager.example.com/graphql",
fetchOptions: {
headers: {
authorization: `Bearer ${personalAccessToken}`,
},
},
});Managing PATs
View Tokens:
- List all your tokens
- See last used time
- Check expiration
Revoke Token:
- Find token in list
- Click Delete
- Confirm deletion
- Token is immediately invalidated
Best Practices:
- Name tokens descriptively
- Set expiration dates
- Rotate tokens regularly
- Revoke unused tokens
- Never commit tokens to git
Machine Users
Creating a Machine User
- Navigate to Machine Users
- Click Create Machine User
- Enter Name
- Select Authentication Type:
- Bearer Token - Token-based (recommended)
- Basic Auth - Username/password
- Click Create
- Copy credentials - shown only once!
Bearer Token Authentication
Simpler and more secure:
bash
curl -H "Authorization: Bearer mu_xyz789..." \
https://manager.example.com/api/machine/checktypescript
const response = await fetch("/api/machine/register-backend", {
method: "POST",
headers: {
Authorization: `Bearer ${machineUserToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
callback_url: "https://backend.example.com/triggers",
application_id: "app-uuid",
}),
});Basic Authentication
Username and password:
bash
curl -u "username:password" \
https://manager.example.com/api/machine/checktypescript
const credentials = btoa(`${username}:${password}`);
const response = await fetch("/api/machine/check", {
headers: {
Authorization: `Basic ${credentials}`,
},
});Machine User Permissions
Machine users are scoped to:
- Single tenant - Cannot access other tenants
- Assigned applications - Only apps they're registered for
- Specific endpoints - Limited API surface
API Endpoints
Check Authentication (Machine User)
Verify machine user credentials:
http
GET /api/machine/check
Authorization: Bearer <token>Response:
json
{
"authenticated": true,
"machine_user_id": "uuid",
"tenant_id": "uuid",
"message": "Authentication successful"
}Register Backend
Register for trigger execution:
http
POST /api/machine/register-backend
Authorization: Bearer <token>
Content-Type: application/json
{
"callback_url": "https://backend.example.com/triggers",
"version": "1.0.0",
"application_id": "uuid"
}Response:
json
{
"success": true,
"backend_id": "uuid",
"message": "Backend registered successfully"
}Security Best Practices
Token Storage
Do:
- Store in environment variables
- Use secrets management (HashiCorp Vault, AWS Secrets Manager)
- Encrypt at rest
Don't:
- Commit to version control
- Hardcode in source code
- Share via unsecured channels
Token Rotation
- Create new token
- Update applications to use new token
- Verify new token works
- Revoke old token
Access Control
- Use least privilege principle
- Create separate tokens per service
- Revoke tokens when no longer needed
- Monitor token usage in audit logs
Network Security
- Use HTTPS only
- Restrict by IP if possible
- Implement rate limiting
- Monitor for unusual patterns
Troubleshooting
401 Unauthorized
Reasons:
- Invalid token
- Expired token
- Token revoked
- Wrong authentication header format
Fix:
- Verify token is correct
- Check token hasn't expired
- Ensure header format:
Authorization: Bearer <token> - Create new token if needed
403 Forbidden
Reasons:
- Valid authentication but insufficient permissions
- Accessing wrong tenant's resources
- Machine user not assigned to application
Fix:
- Verify tenant/application access
- Check user permissions
- Ensure correct resource IDs
Token Not Working After Creation
Check:
- Did you copy the entire token?
- Are there extra spaces or newlines?
- Is the header formatted correctly?
- Try the
/api/machine/checkendpoint to test
Example: Backend Service Authentication
typescript
// backend-service.ts
import fetch from "node-fetch";
const MANAGER_URL = process.env.MANAGER_URL;
const MACHINE_TOKEN = process.env.MACHINE_USER_TOKEN;
const APP_ID = process.env.APPLICATION_ID;
// Register with Manager
async function registerBackend() {
const response = await fetch(`${MANAGER_URL}/api/machine/register-backend`, {
method: "POST",
headers: {
Authorization: `Bearer ${MACHINE_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
callback_url: "https://my-backend.com/triggers",
version: "1.0.0",
application_id: APP_ID,
}),
});
if (!response.ok) {
throw new Error(`Registration failed: ${response.statusText}`);
}
const data = await response.json();
console.log("Backend registered:", data.backend_id);
}
// Verify authentication
async function checkAuth() {
const response = await fetch(`${MANAGER_URL}/api/machine/check`, {
headers: {
Authorization: `Bearer ${MACHINE_TOKEN}`,
},
});
const data = await response.json();
console.log("Authenticated:", data.authenticated);
}
// Start service
async function start() {
await checkAuth();
await registerBackend();
console.log("Service ready");
}
start();See Also
- Personal Access Tokens Guide - User token management
- Machine Users Guide - Service authentication
- Backend Registration - Connect services
- GraphQL API - API usage