<@ULVA73B9P> Is there a possibility to plug Prefec...
# ask-marvin
p
@Marvin Is there a possibility to plug Prefect with a Keycloack in order to give specific access right to some interface/functions ?
m
thought for 105.4 seconds
Short answer: Yes with Prefect Cloud (via SSO + RBAC). Not natively with self‑hosted Prefect Server. Assuming Prefect 3.x: - Prefect Cloud (Enterprise): Supports SSO with any OIDC/SAML IdP, so Keycloak works. You can map users/groups to granular roles to control access to UI/API features (flows, deployments, work pools, automations, etc.). See: - Configure SSO - RBAC and workspace roles - Self‑hosted Prefect Server: No native OIDC/SAML or RBAC. Only basic auth is supported; all authenticated users have full access. You can put a reverse proxy (e.g., Nginx/Traefik with oauth2-proxy/Keycloak) in front to gate access, but Prefect won’t enforce per-user permissions internally. - Security settings (self-hosted) Example for self‑hosted basic auth:
Copy code
# On the server
export PREFECT_SERVER_API_AUTH_STRING="admin:pass"
# On clients/agents
export PREFECT_API_AUTH_STRING="admin:pass"
Questions to help me recommend the best path: - Are you using Prefect Cloud or self-hosted Prefect Server? - Do you need per-role UI/API permissions (RBAC) or just gated access to the UI? - If Cloud: are you able to use the Enterprise plan for SSO/RBAC? If self‑hosted: do you have a reverse proxy where we can add Keycloak auth?
p
@Marvin I'm using a self-hosted Prefect server, I already tried this option PREFECT_SERVER_API_AUTH_STRING but it only ask the password once, it seems that there is no timeout sessions. Do you have some exemples with a reverse-proxy ?
m
thought for 79.5 seconds
You’re right — Prefect Server’s basic auth has no session management. The UI stores the auth locally and reuses it; there’s no idle/absolute timeout. To get real sessions and timeouts, you’ll want to front Prefect with a reverse proxy that handles OIDC with Keycloak. Below are working patterns you can adapt. They gate access to both the UI and API via Keycloak, and you can tune idle/max session lifetimes in Keycloak and the proxy. Option A: Nginx + oauth2-proxy + Keycloak (OIDC) - What it does: oauth2-proxy handles OIDC with Keycloak and manages the session cookie; Nginx enforces auth for all requests and forwards to Prefect. - Where to tune timeouts: in Keycloak (SSO session idle/max, token lifespans) and in oauth2-proxy (cookie_expire, cookie_refresh). 1) oauth2-proxy (config via environment)
Copy code
OAUTH2_PROXY_PROVIDER=oidc
OAUTH2_PROXY_OIDC_ISSUER_URL=<https://keycloak.example.com/realms/myrealm>
OAUTH2_PROXY_CLIENT_ID=prefect-ui
OAUTH2_PROXY_CLIENT_SECRET=YOUR_CLIENT_SECRET
OAUTH2_PROXY_REDIRECT_URL=<https://prefect.example.com/oauth2/callback>
OAUTH2_PROXY_EMAIL_DOMAINS=*
OAUTH2_PROXY_SCOPE=openid email profile
OAUTH2_PROXY_COOKIE_SECRET=BASE64_32_BYTE_SECRET
OAUTH2_PROXY_COOKIE_SECURE=true
OAUTH2_PROXY_COOKIE_SAMESITE=lax
OAUTH2_PROXY_SET_XAUTHREQUEST=true
OAUTH2_PROXY_PASS_ACCESS_TOKEN=true
OAUTH2_PROXY_PASS_AUTHORIZATION_HEADER=true
# Session/timeout knobs
OAUTH2_PROXY_COOKIE_EXPIRE=8h
OAUTH2_PROXY_COOKIE_REFRESH=1h
2) Nginx (enforce auth, proxy to Prefect; includes Upgrade headers for SSE/WebSocket compatibility)
Copy code
server {
  listen 443 ssl;
  server_name <http://prefect.example.com|prefect.example.com>;

  # TLS config omitted for brevity

  # oauth2-proxy endpoints
  location /oauth2/ {
    proxy_pass <http://oauth2-proxy:4180;>
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
  }

  # Auth check for every request
  location = /oauth2/auth {
    proxy_pass <http://oauth2-proxy:4180/oauth2/auth;>
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
  }

  # Protect everything behind oauth2
  location / {
    auth_request /oauth2/auth;
    error_page 401 = /oauth2/start?rd=$request_uri;

    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $host;

    # Forward user info (optional, for logging/auditing)
    proxy_set_header X-Auth-Request-Email $upstream_http_x_auth_request_email;
    proxy_set_header X-Auth-Request-User  $upstream_http_x_auth_request_user;

    # Upgrade for streaming/websocket endpoints if any
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;

    proxy_pass <http://prefect-server:4200;>
  }
}

# Map required for Connection upgrade
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}
3) Keycloak setup - Create a confidential client (e.g., “prefect-ui”) in your realm. - Valid Redirect URI: https://prefect.example.com/oauth2/callback - Web origins: https://prefect.example.com - Adjust session + token settings to control timeouts: - SSO Session Idle / Max - Access token lifespan - Refresh token lifespan Docs: Keycloak session/timeouts 4) Prefect Server - Remove
PREFECT_SERVER_API_AUTH_STRING
so the proxy is the only auth gate. - Point users to https://prefect.example.com - Keep workers and automations pointing at the internal API URL (bypass the proxy), e.g.: -
PREFECT_API_URL=<http://prefect-server:4200/api>
(inside your network) This avoids headless auth issues for workers. Option B: Traefik + oauth2-proxy (ForwardAuth) - Traefik enforces auth via ForwardAuth to oauth2-proxy. - Example (static/dynamic config sketch):
Traefik dynamic middleware (file or labels):
Copy code
http:
  middlewares:
    oauth2-forwardauth:
      forwardAuth:
        address: "<http://oauth2-proxy:4180/oauth2/auth>"
        trustForwardHeader: true
        authResponseHeaders:
          - X-Auth-Request-Email
          - X-Auth-Request-User
Router and service:
Copy code
http:
  routers:
    prefect:
      rule: "Host(`<http://prefect.example.com|prefect.example.com>`)"
      entryPoints: ["websecure"]
      tls: {}
      middlewares: ["oauth2-forwardauth"]
      service: "prefect"

  services:
    prefect:
      loadBalancer:
        servers:
          - url: "<http://prefect-server:4200>"
Expose oauth2-proxy routes through Traefik too (for /oauth2/*) without the ForwardAuth middleware, and configure oauth2-proxy with the same env as in Option A. Session timeout behavior - Prefect’s basic auth has no session timeout; it’s effectively “remembered” until cleared. - With the proxy approach: - Set Keycloak realm SSO idle/max session and token lifespans to your policy. - Set oauth2-proxy cookie_expire/cookie_refresh to align with your policy. - Users will be redirected to re-auth when their session expires. Useful references - Prefect security settings (self-hosted): Security settings (self-hosted) - oauth2-proxy docs: oauth2-proxy - Nginx auth_request: nginx auth_request - Traefik ForwardAuth: Traefik ForwardAuth - Keycloak sessions/timeouts: Keycloak session/timeouts Questions to tailor this for you - Which proxy do you prefer (Nginx or Traefik)? - Will your workers access the API internally (recommended) or through the same external URL? - Do you want to keep Prefect’s basic auth behind the proxy (double gate), or use the proxy as the sole gate?