Skip to main content

Authentication

ConstellationAPI uses a two-layer authentication system:

  1. API Key - For authenticating requests to the API
  2. JWT Token - For providing tenant and connection credentials

Authentication Headers

All protected endpoints require two headers:

HeaderDescriptionExample
X-API-KEYYour internal API key (for authentication)your-secure-api-key
X-JWT-TokenJWT token containing tenant and connection credentialseyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

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 check
  • GET /api-docs - Swagger UI
  • GET /openapi.json - OpenAPI spec
  • GET /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

  1. Use Environment Variables: Store your API key in environment variables, not in code
  2. Rotate Keys Regularly: Change your API key and JWT secret periodically for security
  3. Use HTTPS in Production: Always use HTTPS to protect your API key and JWT token in transit
  4. Limit Key Scope: Use different keys for different environments (dev, staging, prod)
  5. Monitor Usage: Check logs for unauthorized access attempts
  6. Secure JWT Tokens: Keep JWT tokens secure and don't expose them in client-side code

Next Steps