Keycloak Setup ~15 min
Prerequisites
- Keycloak 23 running on
http://localhost:8080 - Admin credentials:
admin/admin(default dev setup)
1. Create the realm
- Open http://localhost:8080/admin
- Hover over the realm dropdown (top left) → Create Realm
- Name:
veni-ai - Click Create
2. Create the client
- Clients → Create client
- Fill in:
| Field | Value |
|---|---|
| Client ID | veni-ai-platform |
| Client type | OpenID Connect |
| Client authentication | Off (public client) |
| Standard flow | On |
| Direct access grants | Off |
- Next → set:
| Field | Value |
|---|---|
| Valid redirect URIs | http://localhost:3000/api/auth/callback |
| Valid post logout URIs | http://localhost:5173/* |
| Web origins | http://localhost:3000, http://localhost:5173 |
- Save
3. Enable PKCE
- Open the client → Advanced tab
- Set Proof Key for Code Exchange Code Challenge Method to
S256 - Save
PKCE must be S256
Shell API generates code_challenge = BASE64URL(SHA256(verifier)). The client must require S256 or Keycloak will reject the token exchange.
4. Add protocol mappers
In the client → Client scopes → veni-ai-platform-dedicated → Add mapper → By configuration:
| Mapper | Token claim name | Property |
|---|---|---|
| User Property | email | |
| User Property | given_name | firstName |
| User Property | family_name | lastName |
| User Attribute | sub | (auto) |
5. Create a test user
- Users → Add user
- Fill: username
veni, emailveni@venizia.ai, first/last name - Create → Credentials tab → Set password →
veni(turn off Temporary)
6. Set Shell API env vars
env
APP_ENV_KEYCLOAK_URL=http://localhost:8080
APP_ENV_KEYCLOAK_INTERNAL_URL=http://localhost:8080
APP_ENV_KEYCLOAK_REALM=veni-ai
APP_ENV_KEYCLOAK_CLIENT_ID=veni-ai-platform
APP_ENV_KEYCLOAK_REDIRECT_URI=http://localhost:3000/api/auth/callbackProduction checklist
- [ ] HTTPS on Keycloak (Let's Encrypt or cert-manager)
- [ ]
APP_ENV_KEYCLOAK_URL= public HTTPS URL - [ ]
APP_ENV_KEYCLOAK_INTERNAL_URL= internal K8s service URL - [ ] Remove
admindefault credentials - [ ] Set session idle timeout (e.g. 30 min)
- [ ] Enable brute force protection (Realm Settings → Security Defenses)
- [ ] Use a confidential client + client secret for backend-only flows