Authentication Setup
Configure authentication and authorization using Keycloak OIDC.
Overview
STOA uses Keycloak for centralized authentication and authorization:
- OIDC/OAuth2 - Industry-standard protocols
- Multi-Realm - Isolated realm per tenant
- JWT Tokens - Stateless token validation
- SSO Support - Single Sign-On across APIs
Keycloak Architecture
┌──────────────────────────────────────────────┐
│ Keycloak Master Realm │
├──────────────────────────────────────────────┤
│ Tenant Realms: │
│ ├── realm-acme │
│ ├── realm-globex │
│ └── realm-initech │
└──────────────────────────────────────────────┘
Each tenant realm contains:
- Users and groups
- Client applications
- Roles and permissions
- Identity providers (SAML, social login)
Setup OIDC for an API
Step 1: Create API Client in Keycloak
STOA automatically creates a client when you register an API:
stoa api register \
--tenant acme \
--name my-api \
--upstream https://api.example.com \
--path /my-api \
--auth-enabled true
This creates:
- Client ID:
api-my-api - Access Type:
confidential - Valid Redirect URIs configured
- Service account enabled
Step 2: Configure Kong OIDC Plugin
STOA configures Kong automatically, but you can customize:
stoa api auth configure \
--tenant acme \
--api my-api \
--issuer https://auth.gostoa.dev/realms/acme \
--client-id api-my-api \
--client-secret <secret> \
--scope openid,profile,email
Step 3: Test Authentication
# Get access token
TOKEN=$(curl -X POST \
https://auth.gostoa.dev/realms/acme/protocol/openid-connect/token \
-d "client_id=api-my-api" \
-d "client_secret=YOUR_SECRET" \
-d "grant_type=client_credentials" \
| jq -r '.access_token')
# Call API with token
curl https://gateway.gostoa.dev/acme/my-api/users \
-H "Authorization: Bearer $TOKEN"
Authentication Flows
1. Client Credentials Flow
For machine-to-machine authentication:
# Request token
POST /realms/{tenant}/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
client_id=api-my-api&
client_secret=SECRET&
grant_type=client_credentials&
scope=api:read api:write
2. Authorization Code Flow
For user authentication (web apps):
# Step 1: Redirect user to login
GET /realms/{tenant}/protocol/openid-connect/auth
?client_id=my-web-app
&redirect_uri=https://myapp.com/callback
&response_type=code
&scope=openid
# Step 2: Exchange code for token
POST /realms/{tenant}/protocol/openid-connect/token
client_id=my-web-app&
code=AUTH_CODE&
grant_type=authorization_code&
redirect_uri=https://myapp.com/callback
3. Resource Owner Password Flow
For trusted applications only:
POST /realms/{tenant}/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
client_id=trusted-app&
client_secret=SECRET&
grant_type=password&
username=user@example.com&
password=userpass
Token Validation
Kong validates JWT tokens automatically:
- Signature Validation - Verifies token signature using Keycloak's public keys
- Expiration Check - Ensures token hasn't expired
- Audience Validation - Checks token is for correct API
- Scope Check - Validates required scopes are present
Role-Based Access Control (RBAC)
Define Roles in Keycloak
# Create realm role
stoa auth role create \
--tenant acme \
--name api-admin \
--description "API Administrator"
# Assign role to user
stoa auth role assign \
--tenant acme \
--user user@example.com \
--role api-admin
Enforce Roles in Kong
# Require specific role for route
stoa api auth require-role \
--tenant acme \
--api my-api \
--path /admin/* \
--role api-admin
Advanced Configuration
Custom Token Claims
Add custom claims to JWT tokens:
stoa auth claim add \
--tenant acme \
--name tenant_id \
--value acme \
--token-type access
Token Lifetime
Configure token expiration:
stoa auth token-lifetime set \
--tenant acme \
--access-token 3600 \
--refresh-token 86400
Identity Provider Federation
Connect external IdPs (SAML, Google, GitHub):
stoa auth idp add \
--tenant acme \
--provider google \
--client-id GOOGLE_CLIENT_ID \
--client-secret GOOGLE_SECRET
Troubleshooting
Token Validation Fails
# Check token details
stoa auth token inspect YOUR_TOKEN
# Verify Keycloak connectivity
stoa auth test-connection --tenant acme
Common Issues
- Invalid signature: Check Keycloak public keys are synced
- Token expired: Refresh token or request new one
- Insufficient scope: Ensure required scopes in token
- Wrong audience: Verify client_id matches API configuration
🚧 Coming Soon: Multi-factor authentication, passwordless auth, and social login integration guides.