Authentication
ConstellationAPI uses a two-layer authentication system:
- API Key - For authenticating requests to the API
- JWT Token - For providing tenant and connection credentials
Authentication Headers
All protected endpoints require two headers:
| Header | Description | Example |
|---|---|---|
X-API-KEY | Your internal API key (for authentication) | your-secure-api-key |
X-JWT-Token | JWT token containing tenant and connection credentials | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... |
Getting Your API Key
The API key is set in your .env file as INTERNAL_API_KEY:
INTERNAL_API_KEY=your_secure_api_key
Important: Keep your API key secure. Never commit it to version control or expose it in client-side code.
JWT Token Structure
The JWT token must contain tenant and connection information:
{
"tenant_id": "tenant-123",
"connections": {
"jira": {
"baseUrl": "https://company.atlassian.net",
"email": "user@example.com",
"apiToken": "jira-api-token"
},
"github": {
"token": "github-personal-access-token"
}
}
}
The JWT token is signed using the JWT_SECRET_KEY configured in your .env file.
Making Authenticated Requests
cURL Example
curl http://localhost:3007/jira/projects \
-H "X-API-KEY: your-internal-key" \
-H "X-JWT-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
JavaScript/Node.js Example
const response = await fetch('http://localhost:3007/jira/projects', {
headers: {
'X-API-KEY': 'your-internal-key',
'X-JWT-Token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
},
});
Python Example
import requests
headers = {
'X-API-KEY': 'your-internal-key',
'X-JWT-Token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
}
response = requests.get(
'http://localhost:3007/jira/projects',
headers=headers
)
Public Endpoints
The following endpoints do not require authentication:
GET /health- Health checkGET /api-docs- Swagger UIGET /openapi.json- OpenAPI specGET /integrations- Available integrations and filterable fields
Authentication Errors
401 Unauthorized
Missing or invalid API key:
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Missing X-API-KEY header"
}
}
Solution: Ensure the X-API-KEY header is present and matches your INTERNAL_API_KEY.
400 Bad Request
Invalid or missing JWT token:
{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "JWT token is required"
}
}
Solution: Ensure the X-JWT-Token header is present and contains a valid JWT token with tenant and connection information.
400 Bad Request - Missing Connection
Connection not found in JWT token:
{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "Jira connection not found in JWT token"
}
}
Solution: Ensure your JWT token includes the required connection configuration (e.g., jira or github) in the connections object.
Best Practices
- Use Environment Variables: Store your API key in environment variables, not in code
- Rotate Keys Regularly: Change your API key and JWT secret periodically for security
- Use HTTPS in Production: Always use HTTPS to protect your API key and JWT token in transit
- Limit Key Scope: Use different keys for different environments (dev, staging, prod)
- Monitor Usage: Check logs for unauthorized access attempts
- Secure JWT Tokens: Keep JWT tokens secure and don't expose them in client-side code
Next Steps
- API Reference - Explore all endpoints
- Integrations - Learn about available integrations