Skip to content

lbrenman/keycloak-dev-codespace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Keycloak Development Environment

A simple setup for running Keycloak in GitHub Codespaces for development work.

Quick Start

  1. Increase your Codespace timeout limit for inactivity as follows:
  • Go to GitHub > Settings > Codespaces
  • Under Idle timeout, increase the value (max is 240 minutes)
  1. Open in Codespaces: Click the green "Code" button in GitHub and select "Create codespace on main" OR click the button below:

    Open in Codespaces

  2. Wait for setup: The environment will automatically set up Keycloak with PostgreSQL

  3. Access Keycloak: Once ready, open http://localhost:8080/admin in your browser

  4. On subsequent Codespace starts, run docker-compose up -d

Getting Started

All references to http://localhost:8080 should use the Codespace forwarded port (e.g. https://animated-space-succotash-wr545qpxc9qgx-8080.app.github.dev).

Default Credentials

  • Admin Console: http://localhost:8080/admin
  • Username: admin
  • Password: admin

What's Included

  • Keycloak 23.0: Latest stable version running in development mode
  • PostgreSQL 15: Database backend for Keycloak
  • Docker Compose: Easy container orchestration
  • VS Code Extensions: JSON, YAML, and Docker support

Development Workflow

Starting the Environment

The environment starts automatically when you open the Codespace. If you need to restart:

docker-compose down
docker-compose up -d

Accessing Services

Custom Themes

Place custom themes in the themes/ directory. They'll be automatically mounted into Keycloak.

Data Persistence

Important: By default, PostgreSQL data persists between Codespace sessions using a bind mount to ./postgres-data/. This directory is stored in the Codespace's persistent storage.

However, if the Codespace is deleted or rebuilt, all data will be lost. For important configurations:

Export Your Realm Configuration

# Export a specific realm
docker-compose exec keycloak /opt/keycloak/bin/kc.sh export --dir /opt/keycloak/data/import --realm your-realm-name

# Export all realms
docker-compose exec keycloak /opt/keycloak/bin/kc.sh export --dir /opt/keycloak/data/import

Import Realm on Startup

Place your realm JSON files in the imports/ directory. They'll be available at /opt/keycloak/data/import inside the container.

Database Access

Connect to PostgreSQL directly:

docker-compose exec keycloak-db psql -U keycloak -d keycloak

Configuration

The setup uses development-friendly configurations:

  • Hostname restrictions disabled
  • HTTPS not enforced
  • Detailed logging enabled
  • Metrics and health endpoints enabled

Troubleshooting

Keycloak won't start

  • Check if ports 8080 or 5432 are already in use
  • Restart the containers: docker-compose restart

Can't access admin console

  • Ensure Keycloak is fully started (check logs: docker-compose logs keycloak)
  • Verify port forwarding is working in Codespaces

Database connection issues

  • Check if PostgreSQL is running: docker-compose ps
  • Restart database: docker-compose restart keycloak-db

Useful Commands

# View logs
docker-compose logs -f keycloak
docker-compose logs -f keycloak-db

# Restart services
docker-compose restart

# Stop everything
docker-compose down

# Start fresh (removes data)
docker-compose down -v
docker-compose up -d

Next Steps

  1. Create your first realm
  2. Configure authentication flows
  3. Set up user federation
  4. Develop custom themes
  5. Integrate with your applications

Resources

JWKS Endpoint URL

https://your-keycloak-url/realms/{realm-name}/protocol/openid-connect/certs

e.g. https://animated-space-succotash-wr545qpxc9qgx-8080.app.github.dev/realms/{realm-name}/protocol/openid-connect/certs

Token URL

https://your-keycloak-url/realms/{realm-name}/protocol/openid-connect/token

e.g. https://animated-space-succotash-wr545qpxc9qgx-8080.app.github.dev/realms/lbrenman/protocol/openid-connect/token

REST API Calls

https://www.keycloak.org/docs-api/latest/rest-api/index.html

Create a Dedicated Service Account Client This is more secure for programmatic access:

Create a client in the Keycloak admin console:

Go to Clients → Create Client Client ID: api-client Client authentication: ON Service accounts roles: ON

Get client credentials from the Credentials tab Use client credentials grant:

# Replace with your actual client secret
CLIENT_SECRET="your-client-secret-here"

TOKEN_RESPONSE=$(curl -s -X POST \
  'https://your-codespace-url.app.github.dev/realms/master/protocol/openid-connect/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials' \
  -d 'client_id=api-client' \
  -d 'client_secret='$CLIENT_SECRET)

ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')

You will need to assign roles to your api-client service account to access the Admin REST API. Here's how to set it up:

Assign Admin Roles to Your Service Account

  1. Go to your realm (lbrenman) in Keycloak admin console
  2. Navigate to: Clients → api-clientService Account Roles tab
  3. Assign roles depending on what level of access you need:

Option A: Full Admin Access (Easiest)

  • Client roles → Select realm-management from dropdown
  • Assign: realm-admin

This gives full administrative access to the realm.

Option B: Specific Permissions (More Secure)

Instead of realm-admin, assign only what you need:

For user management:

  • view-users
  • manage-users
  • create-user

For client management:

  • view-clients
  • manage-clients

For realm configuration:

  • view-realm
  • manage-realm

For identity providers:

  • view-identity-providers
  • manage-identity-providers

Test Your API Access

After assigning roles, test with your token:

# Get token
TOKEN_RESPONSE=$(curl -s --location 'https://animated-space-succotash-wr545qpxc9qgx-8080.app.github.dev/realms/lbrenman/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=client_credentials' \
--data 'client_id=api-client' \
--data 'client_secret=NsFVZCo0Zf8TB4DfwN6cRzSgobgUBbs6')

ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')

# Test API calls
# List users
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
'https://animated-space-succotash-wr545qpxc9qgx-8080.app.github.dev/admin/realms/lbrenman/users'

# Get realm info
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
'https://animated-space-succotash-wr545qpxc9qgx-8080.app.github.dev/admin/realms/lbrenman'

Role Reference

Here are the main realm-management roles and what they allow:

Role Permissions
realm-admin Full administrative access
manage-users Create, update, delete users
view-users Read user information
manage-clients Create, update, delete clients
view-clients Read client information
manage-realm Configure realm settings
view-realm Read realm configuration
manage-identity-providers Configure SSO providers
view-identity-providers Read SSO provider configs

Quick Verification

You can also check what roles your service account has by decoding the JWT token:

# Decode the token payload (requires base64 and jq)
echo $ACCESS_TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | jq '.realm_access.roles'

Start with realm-admin for full access, then narrow it down to specific roles based on your actual needs for better security.

Common API Examples

Once you have an access token:

# List all realms
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
  'https://your-codespace-url.app.github.dev/admin/realms'

# Get users in master realm
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
  'https://your-codespace-url.app.github.dev/admin/realms/master/users'

# Create a new user
curl -X POST \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "testuser",
    "enabled": true,
    "firstName": "Test",
    "lastName": "User",
    "email": "[email protected]"
  }' \
  'https://your-codespace-url.app.github.dev/admin/realms/master/users'

Quick Test Script

Here's a simple script to test the API access:

#!/bin/bash
KEYCLOAK_URL="https://your-codespace-url.app.github.dev"

# Get token using admin credentials
TOKEN_RESPONSE=$(curl -s -X POST \
  "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=password' \
  -d 'client_id=admin-cli' \
  -d 'username=admin' \
  -d 'password=admin')

if [ $? -eq 0 ]; then
  ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')
  
  if [ "$ACCESS_TOKEN" != "null" ] && [ "$ACCESS_TOKEN" != "" ]; then
    echo "✅ Successfully obtained access token"
    
    # Test API call
    curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
      "$KEYCLOAK_URL/admin/realms" | jq '.[].realm'
  else
    echo "❌ Failed to get access token"
    echo $TOKEN_RESPONSE | jq '.'
  fi
else
  echo "❌ Failed to connect to Keycloak"
fi

Client Registration

You can use the admin API with OAuth2 to create and manage clients.

For Dynamic Client Registration you can also create an Initial access token (Client -> Initial access token) and make a call to the /realms/<realm>/clients-registrations/openid-connect endpoint using this Bearer token.

For example:

curl --location 'https://cuddly-train-r44r5655jfx7xv-8080.app.github.dev/realms/lbrenman/clients-registrations/openid-connect' \
--header 'Content-Type: application/json' \
--data '{
  "client_name": "my-test-client",
  "token_endpoint_auth_method": "client_secret_basic",
  "redirect_uris":[
    "https://test123.com/callback"
    ],
  "grant_types":[
    "client_credentials"
    ]
}'

With response:

{
    "redirect_uris": [
        "https://test123.com/callback"
    ],
    "token_endpoint_auth_method": "client_secret_basic",
    "grant_types": [
        "authorization_code",
        "client_credentials"
    ],
    "response_types": [
        "code",
        "none"
    ],
    "client_id": "f5f02504-ebc7-47b4-9082-84798c766d8b",
    "client_secret": "7V63XOsFX97p9I7Z4HimBIhD8sKyTFpM",
    "client_name": "my-client10",
    "scope": "address phone offline_access microprofile-jwt",
    "subject_type": "public",
    "request_uris": [],
    "tls_client_certificate_bound_access_tokens": false,
    "dpop_bound_access_tokens": false,
    "post_logout_redirect_uris": [
        "https://test123.com/callback"
    ],
    "client_id_issued_at": 1748879746,
    "client_secret_expires_at": 0,
    "registration_client_uri": "https://cuddly-train-r44r5655jfx7xv-8080.app.github.dev/realms/lbrenman/clients-registrations/openid-connect/f5f02504-ebc7-47b4-9082-84798c766d8b",
    "registration_access_token": "eyJh...nISuE-54",
    "backchannel_logout_session_required": false,
    "require_pushed_authorization_requests": false,
    "frontchannel_logout_session_required": false
}

About

A Keycloak setup for learning that runs in Codespace

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published