- Created SelfFreezoneClient in Self components
- Wraps SDK FreezoneScriptClient for Self-specific operations
- Implements send_verification_email method
- Uses Rhai script template for email verification
- Includes template variable substitution
- Added serde-wasm-bindgen dependency
Usage:
let client = SelfFreezoneClient::builder()
.supervisor_url("http://localhost:8080")
.secret("my-secret")
.build()?;
client.send_verification_email(
"user@example.com",
"123456",
"https://verify.com/abc"
).await?;
12 KiB
12 KiB
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:
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:
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_credentialsgrant type - ✅ Returns standard token response format
- ✅ Implements proper error responses
- ✅ Validates client authentication
- 🔄 Planned:
authorization_codegrant type - 🔄 Planned:
refresh_tokensupport
Request Format:
{
"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:
{
"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:
{
"sub": "user-unique-identifier",
"email": "user@example.com",
"name": "John Doe",
"public_key": "04a1b2c3d4e5f6...",
"created_at": "1640995200"
}
JWT Token Structure
Access Token Claims
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<String>, // Authentication challenge
}
ID Token (Future Implementation)
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<String>,
name: Option<String>,
picture: Option<String>,
// Authentication context
auth_time: Option<usize>,
nonce: Option<String>,
}
Discovery Document
OpenID Configuration Endpoint
Planned Implementation: /.well-known/openid-configuration
{
"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
{
"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
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
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
// Future implementation: SAML assertion generation
pub struct SamlAssertion {
pub subject: String,
pub issuer: String,
pub audience: String,
pub attributes: HashMap<String, String>,
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
- JWT Signing: Tokens signed with HMAC-SHA256 or RSA-SHA256
- Token Expiration: Short-lived tokens (1 hour default)
- Scope Validation: Strict scope checking for claims
- Audience Validation: Tokens bound to specific audiences
OIDC Security Best Practices
- PKCE Support: Planned for authorization code flow
- State Parameter: Anti-CSRF protection
- Nonce Validation: Replay attack prevention
- HTTPS Only: All endpoints require HTTPS in production
Self-Sovereign Considerations
- No Central Authority: Users control their own identity
- Cryptographic Authentication: No passwords or shared secrets
- Local Key Storage: Private keys never transmitted
- 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
- Authorization Code Flow: Full web application support
- ID Tokens: Standard OIDC ID token implementation
- Refresh Tokens: Long-lived session management
- Discovery Document: Standard OIDC discovery
- JWKS Endpoint: Public key distribution
- PKCE Support: Enhanced security for public clients
Advanced Features
- Federation: Trust relationships with other identity providers
- Delegation: Temporary identity delegation
- Multi-Factor: Additional authentication factors
- Device Flow: Support for device authentication
- Logout: Single logout implementation
Standards Compliance
- RFC 7636: PKCE implementation
- RFC 7662: Token introspection
- RFC 7009: Token revocation
- RFC 8693: Token exchange
- OpenID Connect Session Management: Session handling