diff --git a/docker-compose-examples/grist-traefik-oidc-auth/configs/dex/config.yaml b/docker-compose-examples/grist-traefik-oidc-auth/configs/dex/config.yaml new file mode 100644 index 00000000..75fc136b --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/configs/dex/config.yaml @@ -0,0 +1,61 @@ +# This file uses Go template formatting. + +issuer: {{ getenv "DEX_ISSUER" "http://127.0.0.1:5556/dex" }} + +storage: + type: sqlite3 + config: + file: {{ getenv "DEX_STORAGE_SQLITE3_CONFIG_FILE" "/var/dex/dex.db" }} + +web: +{{- if getenv "DEX_WEB_HTTPS" "" }} + https: {{ .Env.DEX_WEB_HTTPS }} + tlsKey: {{ getenv "DEX_WEB_TLS_KEY" | required "$DEX_WEB_TLS_KEY in case of web.https is enabled" }} + tlsCert: {{ getenv "DEX_WEB_TLS_CERT" | required "$DEX_WEB_TLS_CERT in case of web.https is enabled" }} +{{- end }} + http: {{ getenv "DEX_WEB_HTTP" "0.0.0.0:5556" }} + +{{- if getenv "DEX_TELEMETRY_HTTP" }} +telemetry: + http: {{ .Env.DEX_TELEMETRY_HTTP }} +{{- end }} + +expiry: + deviceRequests: {{ getenv "DEX_EXPIRY_DEVICE_REQUESTS" "5m" }} + signingKeys: {{ getenv "DEX_EXPIRY_SIGNING_KEYS" "6h" }} + idTokens: {{ getenv "DEX_EXPIRY_ID_TOKENS" "24h" }} + authRequests: {{ getenv "DEX_EXPIRY_AUTH_REQUESTS" "24h" }} + +logger: + level: {{ getenv "DEX_LOG_LEVEL" "info" }} + format: {{ getenv "DEX_LOG_FORMAT" "text" }} + +oauth2: + responseTypes: {{ getenv "DEX_OAUTH2_RESPONSE_TYPES" "[code]" }} + skipApprovalScreen: {{ getenv "DEX_OAUTH2_SKIP_APPROVAL_SCREEN" "false" }} + alwaysShowLoginScreen: {{ getenv "DEX_OAUTH2_ALWAYS_SHOW_LOGIN_SCREEN" "false" }} +{{- if getenv "DEX_OAUTH2_PASSWORD_CONNECTOR" "" }} + passwordConnector: {{ .Env.DEX_OAUTH2_PASSWORD_CONNECTOR }} +{{- end }} + +enablePasswordDB: {{ getenv "DEX_ENABLE_PASSWORD_DB" "true" }} + +staticPasswords: + - email: "admin@example.com" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "admin" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" + +staticClients: + - id: grist-client + secret: app-secret + name: 'Private Client' + redirectURIs: + - 'https://example.com/oidc/callback' + +connectors: +{{- if getenv "DEX_CONNECTORS_ENABLE_MOCK" }} +- type: mockCallback + id: mock + name: Example +{{- end }} \ No newline at end of file diff --git a/docker-compose-examples/grist-traefik-oidc-auth/configs/traefik-dynamic-config.yml b/docker-compose-examples/grist-traefik-oidc-auth/configs/traefik-dynamic-config.yml index d77000e6..87861bc8 100644 --- a/docker-compose-examples/grist-traefik-oidc-auth/configs/traefik-dynamic-config.yml +++ b/docker-compose-examples/grist-traefik-oidc-auth/configs/traefik-dynamic-config.yml @@ -1,36 +1,2 @@ http: - # Declaring the user list - middlewares: - grist-basic-auth: - basicAuth: - # The header that Grist will listen for authenticated usernames on. - headerField: "X-Forwarded-User" - # This is the list of users, in the format username:password. - # Passwords can be created using `htpasswd` - # E.g: `htpasswd -nB test@example.org` - users: - # The default username is "test@example.org". The default password is "test". - - "test@example.org:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" - routers: - # General router for almost all Grist traffic. - general: - entrypoints: - - web - - websecure - rule: "HostRegexp(`.*`)" - service: grist@docker - tls: - certresolver: letsencrypt - - # Separate Traefik router for the login pages. - # This allows a user to visit the site without hitting the basic auth login page. - login: - entrypoints: - - web - - websecure - rule: "PathPrefix(`/auth/login`) || PathPrefix(`/_oauth`)" - middlewares: - - grist-basic-auth - service: grist@docker - tls: - certresolver: letsencrypt \ No newline at end of file + # Declaring the user list \ No newline at end of file diff --git a/docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml b/docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml index 6f71c900..49863df2 100644 --- a/docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml +++ b/docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml @@ -16,31 +16,38 @@ secrets: file: ./secrets/SESSION_SECRET STORAGE_ENCRYPTION_KEY: file: ./secrets/STORAGE_ENCRYPTION_KEY - STORAGE_PASSWORD: - file: ./secrets/STORAGE_PASSWORD + # These secrets are for using Authelia as an OIDC provider + HMAC_SECRET: + file: ./secrets/HMAC_SECRET services: -# grist: -# image: gristlabs/grist:latest -# environment: -# # Use Python 3 instead of 2. -# PYTHON_VERSION: 3 -# # Sets the header to look at for authentication -# GRIST_FORWARD_AUTH_HEADER: X-Forwarded-User -# # Forces Grist to only use a single team called 'Example' -# GRIST_SINGLE_ORG: my-grist-team # alternatively, GRIST_ORG_IN_PATH: "true" for multi-team operation -# # Force users to login (disable anonymous access) -# GRIST_FORCE_LOGIN: true -# # Base URL Grist redirects to when navigating. Change this to your domain. -# APP_HOME_URL: https://localhost -# # Default email for the "Admin" account -# GRIST_DEFAULT_EMAIL: test@example.org -# volumes: -# # Where to store persistent data, such as documents. -# - ./grist_local_data:/persist -# labels: -# - "traefik.http.services.grist.loadbalancer.server.port=8484" + grist: + image: gristlabs/grist:latest + ports: + - 8484:8484 + environment: + GRIST_OIDC_IDP_ISSUER: http://dex:5556 + GRIST_OIDC_IDP_CLIENT_ID: grist-client + GRIST_OIDC_IDP_CLIENT_SECRET: app-secret + GRIST_OIDC_IDP_SKIP_END_SESSION_ENDPOINT: true + # Forces Grist to only use a single team called 'Example' + GRIST_SINGLE_ORG: my-grist-team # alternatively, GRIST_ORG_IN_PATH: "true" for multi-team operation + # Force users to login (disable anonymous access) + GRIST_FORCE_LOGIN: true + # Base URL Grist redirects to when navigating. Change this to your domain. + APP_HOME_URL: https://grist.localhost + # Default email for the "Admin" account + GRIST_DEFAULT_EMAIL: test@example.org + volumes: + # Where to store persistent data, such as documents. + - ./grist_local_data:/persist + labels: + - "traefik.http.services.grist.loadbalancer.server.port=8484" + - "traefik.http.routers.grist.rule=Host(`grist.localhost`)" + - "traefik.http.routers.grist.service=grist" + - "traefik.http.routers.grist.tls.certresolver=letsencrypt" +# # traefik: # image: traefik:latest # ports: @@ -59,25 +66,54 @@ services: # # Traefik needs docker access when configured via docker labels. # - /var/run/docker.sock:/var/run/docker.sock # depends_on: -# - grist - authelia: - image: authelia/authelia:4 +# grist: +# condition: service_started +# authelia: +# condition: service_started + +# authelia: +# image: authelia/authelia:4 +# ports: +# - 9091:9091 +# secrets: +# - HMAC_SECRET +# - JWT_SECRET +# - SESSION_SECRET +# - STORAGE_ENCRYPTION_KEY +# environment: +# AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE: '/run/secrets/JWT_SECRET' +# AUTHELIA_SESSION_SECRET_FILE: '/run/secrets/SESSION_SECRET' +# AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE: '/run/secrets/STORAGE_ENCRYPTION_KEY' +# # Domain Grist is hosted at. Custom variable that's interpolated into the Authelia config +# APP_DOMAIN: 'grist.localhost' +# volumes: +# - ./configs/authelia:/config +# command: +# - 'authelia' +# - '--config=/config/configuration.yml' +# # Enables passing environment variables down to the Authelia config. +# - '--config.experimental.filters=template' +# labels: +# - "traefik.http.services.authelia.loadbalancer.server.port=9091" +# - "traefik.http.routers.authelia.rule=Host(`auth.grist.localhost`)" +# - "traefik.http.routers.authelia.service=authelia" +# - "traefik.http.routers.authelia.tls.certresolver=letsencrypt" + + dex: + image: dexidp/dex:latest ports: - - 9091:9091 - secrets: - - JWT_SECRET - - SESSION_SECRET - - STORAGE_ENCRYPTION_KEY + - 5556:5556 + - 5557:5557 environment: - AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE: '/run/secrets/JWT_SECRET' - AUTHELIA_SESSION_SECRET_FILE: '/run/secrets/SESSION_SECRET' - AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE: '/run/secrets/STORAGE_ENCRYPTION_KEY' - APP_DOMAIN: 'grist.localhost' + DEX_ISSUER: http://auth.grist.localhost:5556/ + DEX_STORAGE_SQLITE3_CONFIG_FILE: /dex_db/dex.db + DEX_ENABLE_PASSWORD_DB: true + DEX_OAUTH2_PASSWORD_CONNECTOR: local volumes: - - ./configs/authelia:/config + - ./configs/dex:/config + - ./dex_db:/dex_db command: - - 'authelia' - - '--config=/config/configuration.yml' - - '--config.experimental.filters=template' - + - dex + - serve + - /config/config.yaml diff --git a/docker-compose-examples/grist-traefik-oidc-auth/secrets/HMAC_SECRET b/docker-compose-examples/grist-traefik-oidc-auth/secrets/HMAC_SECRET new file mode 100644 index 00000000..e69de29b