# OpenID Connect Compliance ## Overview Self implements OpenID Connect (OIDC) compatible endpoints while maintaining its self-sovereign identity principles. The implementation provides standard OAuth 2.0 and OIDC flows that can integrate with existing identity providers and relying party applications. ## OpenID Connect Implementation ### Supported Flows #### 1. Client Credentials Flow with Cryptographic Assertions Self implements a modified client credentials flow using cryptographic signatures instead of client secrets: ```mermaid sequenceDiagram participant C as Client participant S as Self Server participant RP as Relying Party Note over C,RP: Authentication Flow C->>S: POST /oauth/token (with signature) S->>S: Verify cryptographic signature S->>C: Return access_token (JWT) C->>S: GET /oauth/userinfo (Bearer token) S->>C: Return user claims C->>RP: Present identity claims ``` #### 2. Authorization Code Flow (Future) Planned implementation for web applications: ```mermaid sequenceDiagram participant U as User participant RP as Relying Party participant S as Self Server U->>RP: Access protected resource RP->>S: Redirect to /oauth/authorize S->>U: Present consent screen U->>S: Approve/deny consent S->>RP: Redirect with authorization code RP->>S: POST /oauth/token (exchange code) S->>RP: Return access_token + id_token ``` ### Endpoint Compliance #### Token Endpoint - `/oauth/token` **OAuth 2.0 Compliance:** - ✅ Supports `client_credentials` grant type - ✅ Returns standard token response format - ✅ Implements proper error responses - ✅ Validates client authentication - 🔄 Planned: `authorization_code` grant type - 🔄 Planned: `refresh_token` support **Request Format:** ```json { "grant_type": "client_credentials", "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", "client_assertion": "signed-jwt-containing-challenge-response", "public_key": "client-identifier", "challenge": "server-provided-challenge", "scope": "openid profile" } ``` **Response Format:** ```json { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "scope": "openid profile" } ``` #### UserInfo Endpoint - `/oauth/userinfo` **OpenID Connect Compliance:** - ✅ Requires Bearer token authentication - ✅ Returns standard OIDC claims - ✅ Supports CORS for cross-origin requests - ✅ Validates JWT token signatures - ✅ Returns appropriate error responses **Response Format:** ```json { "sub": "user-unique-identifier", "email": "user@example.com", "name": "John Doe", "public_key": "04a1b2c3d4e5f6...", "created_at": "1640995200" } ``` ### JWT Token Structure #### Access Token Claims ```rust struct Claims { // Standard OIDC claims sub: String, // Subject identifier (public key) iss: String, // Issuer ("self-sovereign-identity") aud: String, // Audience ("identity-server") exp: usize, // Expiration time iat: usize, // Issued at time // OAuth 2.0 claims scope: String, // Granted scopes // Self-specific claims challenge: Option, // Authentication challenge } ``` #### ID Token (Future Implementation) ```rust struct IdTokenClaims { // Required OIDC claims sub: String, // Subject identifier iss: String, // Issuer aud: String, // Audience (client_id) exp: usize, // Expiration time iat: usize, // Issued at time // Optional OIDC claims email: Option, name: Option, picture: Option, // Authentication context auth_time: Option, nonce: Option, } ``` ## Discovery Document ### OpenID Configuration Endpoint **Planned Implementation:** `/.well-known/openid-configuration` ```json { "issuer": "https://identity.example.com", "authorization_endpoint": "https://identity.example.com/oauth/authorize", "token_endpoint": "https://identity.example.com/oauth/token", "userinfo_endpoint": "https://identity.example.com/oauth/userinfo", "jwks_uri": "https://identity.example.com/.well-known/jwks.json", "response_types_supported": [ "code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token" ], "grant_types_supported": [ "authorization_code", "client_credentials", "refresh_token" ], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["HS256", "RS256"], "scopes_supported": [ "openid", "profile", "email" ], "claims_supported": [ "sub", "iss", "aud", "exp", "iat", "email", "name", "public_key", "created_at" ], "token_endpoint_auth_methods_supported": [ "client_secret_post", "client_assertion" ], "token_endpoint_auth_signing_alg_values_supported": ["HS256", "RS256"] } ``` ### JWKS Endpoint **Planned Implementation:** `/.well-known/jwks.json` ```json { "keys": [ { "kty": "oct", "use": "sig", "kid": "self-signing-key-1", "alg": "HS256", "k": "base64url-encoded-secret" } ] } ``` ## Scope and Claims Mapping ### Supported Scopes | Scope | Description | Claims Returned | |-------|-------------|-----------------| | `openid` | OpenID Connect authentication | `sub`, `iss`, `aud`, `exp`, `iat` | | `profile` | Basic profile information | `name`, `public_key`, `created_at` | | `email` | Email address | `email` | ### Claim Definitions | Claim | Type | Description | Source | |-------|------|-------------|--------| | `sub` | string | Subject identifier (unique user ID) | User record ID | | `email` | string | Email address | User registration | | `name` | string | Display name | User registration | | `public_key` | string | Cryptographic public key | Key generation | | `created_at` | string | Account creation timestamp | Registration time | ## Integration Examples ### Relying Party Integration #### JavaScript Client ```javascript class SelfOIDCClient { constructor(issuer, clientId) { this.issuer = issuer; this.clientId = clientId; } async authenticate(publicKey, signature, challenge) { const tokenResponse = await fetch(`${this.issuer}/oauth/token`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ grant_type: 'client_credentials', client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', client_assertion: signature, public_key: publicKey, challenge: challenge, scope: 'openid profile email' }) }); const tokens = await tokenResponse.json(); // Get user info const userInfoResponse = await fetch(`${this.issuer}/oauth/userinfo`, { headers: { 'Authorization': `Bearer ${tokens.access_token}` } }); return await userInfoResponse.json(); } } ``` #### Node.js Server ```javascript const express = require('express'); const jwt = require('jsonwebtoken'); const app = express(); // Middleware to verify Self tokens function verifySelfToken(req, res, next) { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ error: 'Missing or invalid authorization header' }); } const token = authHeader.substring(7); try { // Verify token with Self's public key or shared secret const decoded = jwt.verify(token, process.env.SELF_JWT_SECRET); req.user = decoded; next(); } catch (error) { return res.status(401).json({ error: 'Invalid token' }); } } // Protected route app.get('/protected', verifySelfToken, (req, res) => { res.json({ message: 'Access granted', user: req.user }); }); ``` ### Identity Provider Integration #### SAML Bridge ```rust // Future implementation: SAML assertion generation pub struct SamlAssertion { pub subject: String, pub issuer: String, pub audience: String, pub attributes: HashMap, pub signature: String, } impl SamlAssertion { pub fn from_oidc_claims(claims: &Claims) -> Self { let mut attributes = HashMap::new(); attributes.insert("email".to_string(), claims.email.clone()); attributes.insert("name".to_string(), claims.name.clone()); attributes.insert("public_key".to_string(), claims.public_key.clone()); SamlAssertion { subject: claims.sub.clone(), issuer: claims.iss.clone(), audience: "saml-service-provider".to_string(), attributes, signature: "".to_string(), // Generate SAML signature } } } ``` ## Security Considerations ### Token Security 1. **JWT Signing**: Tokens signed with HMAC-SHA256 or RSA-SHA256 2. **Token Expiration**: Short-lived tokens (1 hour default) 3. **Scope Validation**: Strict scope checking for claims 4. **Audience Validation**: Tokens bound to specific audiences ### OIDC Security Best Practices 1. **PKCE Support**: Planned for authorization code flow 2. **State Parameter**: Anti-CSRF protection 3. **Nonce Validation**: Replay attack prevention 4. **HTTPS Only**: All endpoints require HTTPS in production ### Self-Sovereign Considerations 1. **No Central Authority**: Users control their own identity 2. **Cryptographic Authentication**: No passwords or shared secrets 3. **Local Key Storage**: Private keys never transmitted 4. **Minimal Data Collection**: Only necessary claims stored ## Compliance Status ### OAuth 2.0 RFC 6749 | Requirement | Status | Notes | |-------------|--------|-------| | Authorization Endpoint | 🔄 Planned | For authorization code flow | | Token Endpoint | ✅ Implemented | Client credentials flow | | Error Responses | ✅ Implemented | Standard error format | | Access Token Format | ✅ Implemented | JWT tokens | | Scope Parameter | ✅ Implemented | openid, profile, email | ### OpenID Connect Core 1.0 | Requirement | Status | Notes | |-------------|--------|-------| | ID Token | 🔄 Planned | JWT format with required claims | | UserInfo Endpoint | ✅ Implemented | Standard claims format | | Discovery | 🔄 Planned | .well-known/openid-configuration | | Authentication | ✅ Implemented | Cryptographic challenge-response | | Claims | ✅ Implemented | Standard and custom claims | ### OpenID Connect Discovery 1.0 | Requirement | Status | Notes | |-------------|--------|-------| | Configuration Endpoint | 🔄 Planned | Metadata document | | JWKS Endpoint | 🔄 Planned | Public key distribution | | Dynamic Registration | ❌ Not Planned | Self-sovereign model | ## Future Enhancements ### Planned Features 1. **Authorization Code Flow**: Full web application support 2. **ID Tokens**: Standard OIDC ID token implementation 3. **Refresh Tokens**: Long-lived session management 4. **Discovery Document**: Standard OIDC discovery 5. **JWKS Endpoint**: Public key distribution 6. **PKCE Support**: Enhanced security for public clients ### Advanced Features 1. **Federation**: Trust relationships with other identity providers 2. **Delegation**: Temporary identity delegation 3. **Multi-Factor**: Additional authentication factors 4. **Device Flow**: Support for device authentication 5. **Logout**: Single logout implementation ### Standards Compliance 1. **RFC 7636**: PKCE implementation 2. **RFC 7662**: Token introspection 3. **RFC 7009**: Token revocation 4. **RFC 8693**: Token exchange 5. **OpenID Connect Session Management**: Session handling