Skip to content

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"]
JWT_SECRET any Local JWT secret (when OIDC is off) [when OIDC is set → otherwise default="supersecret"]
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) [when OIDC is set → otherwise default="root"]
AUTH_CLIENT_ID any Client ID (local auth) [when OIDC is set → otherwise default="root"]
AUTH_CLIENT_TENANT string Tenant to which this client should be added [optional]
AUTH_CLIENT_ROLES any Roles assigned to this client [when OIDC is set → otherwise default="all"]

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.


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.

EUDIPLO includes a built-in OAuth2 server for simple deployments:

  1. Swagger UI Authentication:

  2. Navigate to the Swagger UI at /api

  3. Click the "Authorize" button
  4. Select "oauth2"
  5. Enter client ID and secret (configured via environment variables)
  6. Click "Authorize"

  7. 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:

curl -X POST http://localhost:3000/oauth2/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "your-client-id",
    "client_secret": "your-client-secret"
  }'

External OIDC Provider

For enterprise deployments with existing identity infrastructure, EUDIPLO can integrate with external OIDC providers like Keycloak, Auth0, or Azure AD.

Configuration:

OIDC=https://your-keycloak.example.com/realms/your-realm
PUBLIC_URL=https://your-api.example.com

Authentication Flow:

  1. Use your OIDC provider's token endpoint with client credentials flow
  2. 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
PUBLIC_URL=https://your-api.example.com
JWT_SECRET=your-secret-key-here-minimum-32-characters
AUTH_CLIENT_ID=root
AUTH_CLIENT_SECRET=root

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:

export enum Role {
    //to manage presentation resources
    Presentations = "presentation:manage",
    // to create offers
    PresentationOffer = "presentation:offer",
    // 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",
}

export function getRoles(type: "all") {
    if (type === "all") {
        return Object.values(Role);
    }
    return [];
}

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.

Troubleshooting

Token Validation Errors

  1. Verify that tokens include the correct audience (eudiplo-service)
  2. Ensure clock synchronization between client and server
  3. Check token expiration times

Integrated OAuth2 Server Issues

  1. Verify JWT_SECRET is at least 32 characters
  2. Ensure client credentials (AUTH_CLIENT_ID/AUTH_CLIENT_SECRET) are configured correctly
  3. Check that PUBLIC_URL is 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_IN to another value, default value is 24h.
  • 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

Architecture & Design

Implementation Guides

Operations