API Authentication¶
EUDIPLO uses OAuth 2.0 Client Credentials flow for API authentication, designed for service-to-service communication without user interaction.
Configuration¶
| Key | Type | Notes |
|---|---|---|
OIDC |
string |
Enable OIDC mode |
OIDC_INTERNAL_ISSUER_URL |
string |
Internal issuer URL in OIDC mode [when OIDC is set → then default=undefined] |
OIDC_CLIENT_ID |
any |
Client ID for OIDC [when OIDC is set → then required] |
OIDC_CLIENT_SECRET |
any |
Client secret for OIDC [when OIDC is set → then required] |
OIDC_SUB |
any |
Claim to use as subject [when OIDC is set → then default="tenant_id"] |
OIDC_ALGORITHM |
any |
Expected JWT alg [when OIDC is set → then default="RS256"] |
MASTER_SECRET |
any |
Master secret for JWT signing and encryption key derivation - required, minimum 32 characters [when OIDC is set → otherwise required] |
JWT_ISSUER |
any |
Local JWT issuer [when OIDC is set → otherwise default="eudiplo-service"] |
JWT_EXPIRES_IN |
any |
Local JWT expiration [when OIDC is set → otherwise default="24h"] |
AUTH_CLIENT_SECRET |
any |
Client secret (local auth) - required when OIDC is not enabled [when OIDC is set → otherwise required] |
AUTH_CLIENT_ID |
any |
Client ID (local auth) - required when OIDC is not enabled [when OIDC is set → otherwise required] |
Authentication Architecture¶
Design Principles¶
- Service-to-Service: No user interaction required
- Tenant Isolation: JWTs are used to isolate tenant data
- Pluggable Identity: Support for both built-in and external OIDC providers
- Stateless: JWT tokens enable horizontal scaling
Security Model¶
- All management endpoints require authentication
- Tenant data is isolated using JWT subject claims
- Tokens are signed and validated for integrity
- Support for token expiration and rotation
- Endpoints are role based protected
Related Architecture: For multi-tenant configuration and session management, see Tenant-Based Architecture and Sessions.
Import¶
Clients can be imported via configuration files. See Configuration Import for details.
OAuth2 Client Credentials Authentication¶
This API exclusively uses the OAuth2 client credentials flow, which is designed for service-to-service authentication where no user interaction is required.
Built-in OAuth2 Server (Recommended for Getting Started)¶
EUDIPLO includes a built-in OAuth2 server for simple deployments:
-
Swagger UI Authentication:
- Navigate to the Swagger UI at
/api - Click the "Authorize" button
- Select "oauth2"
- Enter client ID and secret (configured via environment variables)
- Click "Authorize"
- Navigate to the Swagger UI at
-
Programmatic Access:
Option 1: Credentials in Authorization Header (OAuth2 Standard):
curl -X POST http://localhost:3000/oauth2/token \ -H "Content-Type: application/json" \ -H "Authorization: Basic $(echo -n 'client_id:client_secret' | base64)" \ -d '{ "grant_type": "client_credentials" }'Option 2: Credentials in Request Body:
External OIDC Provider¶
For enterprise deployments with existing identity infrastructure, EUDIPLO can integrate with external OIDC providers like Keycloak, Auth0, or Azure AD.
Configuration:
Authentication Flow:
- Use your OIDC provider's token endpoint with client credentials flow
- Include the access token in API requests:
Authorization: Bearer <token>
Configuration¶
External OIDC Provider¶
# Enable external OIDC
OIDC=true
OIDC_INTERNAL_ISSUER_URL=https://your-keycloak.example.com/realms/your-realm
PUBLIC_URL=https://your-api.example.com
Integrated OAuth2 Server¶
# Leave OIDC undefined for integrated OAuth2 server
# All three values below are REQUIRED
PUBLIC_URL=https://your-api.example.com
MASTER_SECRET=your-secret-key-here-minimum-32-characters
AUTH_CLIENT_ID=your-client-id
AUTH_CLIENT_SECRET=your-client-secret
Security: Secrets are hashed
Client secrets are securely hashed (bcrypt) before storage. They cannot be retrieved after creation. Use the Rotate Secret API endpoint or Web Client button to generate a new secret if needed.
Configuration Reference: For complete configuration options and environment variables, see Key Management and Database Configuration.
Protected Endpoints¶
All administrative endpoints require OAuth2 authentication and are protected by a role based access control approach.
The following roles are available:
/**
* Enumeration of all roles available in the system.
*/
export enum Role {
//to manage presentation resources
Presentations = "presentation:manage",
// to create offers
PresentationRequest = "presentation:request",
// to manage issuance resources
Issuances = "issuance:manage",
// to create offers
IssuanceOffer = "issuance:offer",
// to manage client resources
Clients = "clients:manage",
// to manage tenant resources
Tenants = "tenants:manage",
// to manage registrar configuration and operations
Registrar = "registrar:manage",
}
/**
* List of all roles
*/
export const allRoles = [
Role.Tenants,
Role.IssuanceOffer,
Role.Issuances,
Role.PresentationRequest,
Role.Presentations,
Role.Clients,
Role.Registrar,
];
Each client can have multiple roles assigned, but each client can only be assigned to one tenant at maximum. The client with the tenant manage must not be assigned to any tenant since it is managing the service in general. There could be other roles in the future like limited access to the metrics endpoint.
Resource-Level Access Control¶
In addition to role-based access control, clients can be restricted to specific presentation or issuance configurations. This allows for fine-grained control over which configurations a service account can use.
Configuration Fields:
allowedPresentationConfigs: Array of presentation config IDs. If empty or null, the client can use any presentation config.allowedIssuanceConfigs: Array of issuance config IDs. If empty or null, the client can use any issuance config.
Example: Creating a Restricted Client
curl -X POST http://localhost:3000/clients \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"clientId": "partner-service",
"roles": ["presentation:request", "issuance:offer"],
"allowedPresentationConfigs": ["age-verification", "identity-check"],
"allowedIssuanceConfigs": ["partner-credential"]
}'
This client can only:
- Create presentation requests for
age-verificationandidentity-checkconfigs - Create issuance offers for
partner-credentialconfig
If the client attempts to use a config not in their allowed list, a 403 Forbidden error is returned.
Use Cases:
- Partner Integrations: Limit external partners to specific credential types
- Department Isolation: Different departments use different credential configurations
- Compliance: Ensure services only access configurations they are authorized to use
Note: These restrictions work with both the built-in OAuth2 server and external OIDC providers (e.g., Keycloak). When using an external OIDC provider, the restrictions are stored in EUDIPLO's database and applied during request validation.
Troubleshooting¶
Token Validation Errors¶
- Verify that tokens include the correct audience (
eudiplo-service) - Ensure clock synchronization between client and server
- Check token expiration times
Integrated OAuth2 Server Issues¶
- Verify
MASTER_SECRETis at least 32 characters - Ensure client credentials (
AUTH_CLIENT_ID/AUTH_CLIENT_SECRET) are configured correctly - Check that
PUBLIC_URLis accessible for OAuth2 flows
Security Considerations¶
- Token Lifetime: Tokens expire after 24 hours for client credentials flow. It can be updated by setting the
JWT_EXPIRES_INto another value, default value is24h. - Secure Storage: Store client credentials and tokens securely and never expose them in logs or URLs
- Service-to-Service: This API is designed for service-to-service authentication without user interaction