OIDC groups implementation
- Add Groups field to User struct with JSON storage - Include GetGroups() and SetGroups() helper methods - Extract groups from OIDC claims in FromClaim() - Add database migration 202509161200 for groups column - Update config-example.yaml with groups scope - Add comprehensive documentation and testing
This commit is contained in:
parent
30d12dafed
commit
5abc3c87b2
29 changed files with 5088 additions and 3 deletions
152
docker-dev/docker-compose-oidc-test.yml
Normal file
152
docker-dev/docker-compose-oidc-test.yml
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
services:
|
||||
# PostgreSQL database for Keycloak
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: headscale-postgres
|
||||
environment:
|
||||
POSTGRES_DB: keycloak
|
||||
POSTGRES_USER: keycloak
|
||||
POSTGRES_PASSWORD: password
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
headscale-net:
|
||||
ipv4_address: 10.99.0.5
|
||||
|
||||
# Keycloak OIDC provider
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:23.0
|
||||
container_name: headscale-keycloak
|
||||
environment:
|
||||
KEYCLOAK_ADMIN: admin
|
||||
KEYCLOAK_ADMIN_PASSWORD: admin
|
||||
KC_DB: postgres
|
||||
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
|
||||
KC_DB_USERNAME: keycloak
|
||||
KC_DB_PASSWORD: password
|
||||
KC_HOSTNAME_STRICT: false
|
||||
KC_HOSTNAME_STRICT_HTTPS: false
|
||||
ports:
|
||||
- "8280:8080" # Keycloak admin console
|
||||
depends_on:
|
||||
- postgres
|
||||
networks:
|
||||
headscale-net:
|
||||
ipv4_address: 10.99.0.6
|
||||
command: start-dev
|
||||
volumes:
|
||||
- ./keycloak-config:/opt/keycloak/data/import:ro
|
||||
|
||||
# Build Headscale with our OIDC groups changes
|
||||
headscale:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: Dockerfile.debug
|
||||
container_name: headscale-server
|
||||
volumes:
|
||||
- ./headscale-config-oidc.yaml:/etc/headscale/config.yaml
|
||||
- ./acl.hujson:/etc/headscale/acl.hujson
|
||||
- headscale-data:/var/lib/headscale
|
||||
ports:
|
||||
- "8180:8080" # HTTP API
|
||||
- "9090:9090" # Metrics
|
||||
- "50443:50443" # gRPC
|
||||
command: serve
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
headscale-net:
|
||||
ipv4_address: 10.99.0.10
|
||||
depends_on:
|
||||
- keycloak
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
|
||||
# Headplane with OIDC configuration
|
||||
headplane:
|
||||
build:
|
||||
context: ../../headplane
|
||||
dockerfile: Dockerfile
|
||||
container_name: headscale-headplane
|
||||
ports:
|
||||
- "3000:3000" # Headplane UI
|
||||
environment:
|
||||
- HEADPLANE_CONFIG_PATH=/app/config.yaml
|
||||
volumes:
|
||||
- ./headplane-config-oidc.yaml:/app/config.yaml:ro
|
||||
networks:
|
||||
headscale-net:
|
||||
ipv4_address: 10.99.0.15
|
||||
depends_on:
|
||||
- headscale
|
||||
restart: unless-stopped
|
||||
|
||||
# Test tailscale clients (unchanged)
|
||||
tailscale-client1:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: tailscale-client1
|
||||
hostname: client1
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
environment:
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
- TS_EXTRA_ARGS=--login-server=http://headscale:8080
|
||||
- TS_HOSTNAME=client1
|
||||
- TS_AUTHKEY=${TS_AUTHKEY_CLIENT1:-}
|
||||
- TS_ACCEPT_ROUTES=true
|
||||
- TS_USERSPACE=false
|
||||
volumes:
|
||||
- tailscale-client1-state:/var/lib/tailscale
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
- ./scripts/client-init.sh:/usr/local/bin/client-init.sh:ro
|
||||
networks:
|
||||
headscale-net:
|
||||
ipv4_address: 10.99.0.21
|
||||
depends_on:
|
||||
- headscale
|
||||
restart: unless-stopped
|
||||
command: sh -c "tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock --tun=userspace-networking & sleep 5 && /usr/local/bin/client-init.sh client1 && wait"
|
||||
|
||||
tailscale-client2:
|
||||
image: tailscale/tailscale:latest
|
||||
container_name: tailscale-client2
|
||||
hostname: client2
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
environment:
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
- TS_EXTRA_ARGS=--login-server=http://headscale:8080
|
||||
- TS_HOSTNAME=client2
|
||||
- TS_AUTHKEY=${TS_AUTHKEY_CLIENT2:-}
|
||||
- TS_ACCEPT_ROUTES=true
|
||||
- TS_USERSPACE=false
|
||||
volumes:
|
||||
- tailscale-client2-state:/var/lib/tailscale
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
- ./scripts/client-init.sh:/usr/local/bin/client-init.sh:ro
|
||||
networks:
|
||||
headscale-net:
|
||||
ipv4_address: 10.99.0.22
|
||||
depends_on:
|
||||
- headscale
|
||||
restart: unless-stopped
|
||||
command: sh -c "tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock --tun=userspace-networking & sleep 5 && /usr/local/bin/client-init.sh client2 && wait"
|
||||
|
||||
networks:
|
||||
headscale-net:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 10.99.0.0/24
|
||||
gateway: 10.99.0.1
|
||||
|
||||
volumes:
|
||||
headscale-data:
|
||||
tailscale-client1-state:
|
||||
tailscale-client2-state:
|
||||
postgres-data:
|
||||
Loading…
Add table
Add a link
Reference in a new issue