Authentication API
DRAFT — Internal Developer Use Only
This API reference is for internal development teams.
Overview
What it is: The authentication API provides token-based access to all Discovery endpoints. Three methods are available depending on the integration type.
Why it matters: Every API call requires a valid token. Service-to-service integrations like Hydden Control use API credentials, while interactive sessions may use OTP or OAuth.
Endpoints
Token Generation
| Method | Path | Description | Auth required |
|---|---|---|---|
POST | /auth/api | Authenticate with API credentials | None (credentials in body) |
POST | /auth/otp | Authenticate with one-time password | None (credentials in body) |
POST | /oauth/token | OAuth 2.0 token endpoint | Basic Auth header |
Token Management
| Method | Path | Description | Auth required |
|---|---|---|---|
GET | /internal/v1/token/renew | Renew an expiring access token | JWT cookie |
GET | /internal/v1/user/info | Get current authenticated user info | JWT cookie |
GET | /internal/v1/version | Get API version | JWT cookie |
GET | /internal/v1/features | Get enabled feature flags | JWT cookie |
OIDC Provider Management
| Method | Path | Description | Auth required |
|---|---|---|---|
GET | /internal/v1/oidc/providers | List OIDC providers | JWT cookie |
GET | /internal/v1/oidc/registration | Get registration status | JWT cookie |
POST | /internal/v1/oidc/registration/accept | Accept OIDC registration | JWT cookie |
POST | /internal/v1/oidc/registration/reject | Reject OIDC registration | JWT cookie |
GET | /internal/v1/oidc/registration/join | OIDC registration join flow | JWT cookie |
Access Control
| Method | Path | Description | Auth required |
|---|---|---|---|
GET | /internal/v1/access/role | Get current user role and permissions | JWT cookie |
GET | /internal/v1/access/role/*action | Check permission for a specific action | JWT cookie |
Nonce
| Method | Path | Description | Auth required |
|---|---|---|---|
GET | /auth/nonce/:nonce | Retrieve a nonce value | None |
POST | /auth/nonce | Create a new nonce | None |
POST /auth/api
Authenticate with API client credentials. This is the primary method for service-to-service communication.
Request:
POST /auth/api
Content-Type: application/json
{
"id": "your-client-id",
"secret": "your-client-secret",
"code": "optional-tenant-code"
}Response (200):
{
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"expiresIn": 3600,
"tokenType": "Bearer"
}Error responses:
| Code | Reason |
|---|---|
401 | Invalid credentials |
403 | Client disabled or tenant mismatch |
Control Integration
Hydden Control authenticates using this endpoint. The HTTPClient sends ClientID and ClientSecret from encrypted integration settings:
// Control's authentication flow (simplified)
POST {DiscoveryBaseURL}/auth/api
Body: {"id": clientID, "secret": decryptedSecret}
// Token is cached per tenant with TTL from expiresIn
// Automatic retry with exponential backoff on 429/5xxControl caches tokens per tenant and refreshes them before expiry. The token cache uses a read-write mutex for thread safety.
POST /auth/otp
Authenticate with a one-time password.
Request:
POST /auth/otp
Content-Type: application/json
{
"id": "user-identifier",
"secret": "otp-secret",
"code": "one-time-code"
}Response: Same format as /auth/api.
POST /oauth/token
Standard OAuth 2.0 token endpoint. Supports Basic Auth header for client credentials.
Request:
POST /oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentialsResponse (200):
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}GET /internal/v1/token/renew
Renew the current access token before it expires. Requires an active JWT cookie session.
Request:
GET /internal/v1/token/renew
Cookie: jwt=<current-token>Response (200):
{
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"expiresIn": 3600
}GET /internal/v1/user/info
Get information about the currently authenticated user.
Request:
GET /internal/v1/user/info
Authorization: Bearer <token>Response (200):
{
"userId": "user-uuid",
"email": "user@example.com",
"role": "admin",
"tenantId": "tenant-uuid"
}