Identity & Authentication¶
MeshFlows supports layered authentication across edge, orchestration, and internal service calls.
Authentication Layers¶
- Edge layer (Gateway): validates every inbound request before proxying. Supports JWT tokens and API keys. See Gateway Hardening for full details.
- Execution layer (Orchestrator): validates invocation auth for
/run*and/invoke/scheduled. - Internal admin layer: token-based protection for sensitive operations.
JWT Tokens (User & Service Sessions)¶
The identity service issues HS256-signed JWTs via POST /auth/token:
POST /auth/token
Content-Type: application/json
{"username": "alice", "password": "secret"}
Relevant env vars on the identity service:
| Variable | Description |
|---|---|
IDENTITY_JWT_SECRET |
Signing key (shared with gateway) |
IDENTITY_JWT_ISSUER |
iss claim value (default: meshflows-identity) |
IDENTITY_JWT_AUDIENCE |
aud claim value (default: meshflows) |
API Keys¶
Long-lived machine tokens for CI systems, integrations, and developer access. Managed via the identity service and validated by the gateway with a 60-second local cache.
See API Keys & Products for the full reference.
Google OAuth (Social Login)¶
Users can sign in with a Google account. Identity auto-provisions a local account on first login.
Configuration¶
Set the following environment variables on the identity service (via the meshflows-google-oauth Kubernetes secret):
| Variable | Description |
|---|---|
GOOGLE_CLIENT_ID |
OAuth client ID from Google Cloud Console |
GOOGLE_CLIENT_SECRET |
OAuth client secret |
GOOGLE_REDIRECT_URI |
Callback URL on the identity service (e.g. https://id.meshflows.org/auth/google/callback) |
GOOGLE_DASHBOARD_CALLBACK_URL |
Where to redirect after login (e.g. https://dashboard.meshflows.org/login) |
IDENTITY_GOOGLE_ALLOWED_DOMAINS |
Comma-separated allowed email domains, e.g. mijnbedrijf.nl,partner.nl (empty = any domain) |
IDENTITY_GOOGLE_AUTO_PROVISION |
true (default) / false — auto-create local account on first login |
Login Flow¶
- Frontend redirects to
GET /auth/google/authorize→ identity redirects to Google consent screen - Google redirects back to
GET /auth/google/callback - Identity validates the code, checks domain restriction, auto-provisions user if needed
- Redirects to
GOOGLE_DASHBOARD_CALLBACK_URL#access_token=<jwt> - Frontend extracts token from URL fragment and stores it locally
Deployment¶
The CI/CD pipeline creates the meshflows-google-oauth secret when GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET repository secrets are set. If the secret is absent, Google login is simply disabled — all other auth mechanisms remain unaffected.
Admin Endpoints¶
| Method | Path | Description |
|---|---|---|
PUT |
/users/{username}/oauth/google |
Link a Google account to an existing user |
DELETE |
/users/{username}/oauth/google |
Unlink Google account from a user |
Authentik OIDC (SSO)¶
Users can sign in with Authentik (or any upstream IdP configured in Authentik). Identity auto-provisions a local account on first login.
Configuration¶
Set the following environment variables on the identity service (via the meshflows-authentik-oidc Kubernetes secret):
| Variable | Description |
|---|---|
AUTHENTIK_ISSUER_URL |
OIDC issuer URL (e.g. https://auth.meshflows.org/application/o/meshflows/) |
AUTHENTIK_CLIENT_ID |
OIDC client ID from Authentik |
AUTHENTIK_CLIENT_SECRET |
OIDC client secret |
AUTHENTIK_REDIRECT_URI |
Callback URL on the identity service (e.g. https://id.meshflows.org/auth/authentik/callback) |
AUTHENTIK_DASHBOARD_CALLBACK_URL |
Where to redirect after login (e.g. https://dashboard.meshflows.org/login) |
AUTHENTIK_REGISTER_URL |
Optional self-service registration URL shown on the dashboard |
AUTHENTIK_AUTH_URL |
Optional override for the OIDC authorization endpoint |
AUTHENTIK_TOKEN_URL |
Optional override for the OIDC token endpoint |
AUTHENTIK_USERINFO_URL |
Optional override for the OIDC userinfo endpoint |
AUTHENTIK_SCOPES |
Optional scopes (default: openid email profile) |
IDENTITY_AUTHENTIK_ALLOWED_DOMAINS |
Comma-separated allowed email domains (empty = any domain) |
IDENTITY_AUTHENTIK_AUTO_PROVISION |
true (default) / false — auto-create local account on first login |
Login Flow¶
- Frontend redirects to
GET /auth/authentik/authorize→ identity redirects to Authentik - Authentik redirects back to
GET /auth/authentik/callback - Identity validates the code, checks domain restriction, auto-provisions user if needed
- Redirects to
AUTHENTIK_DASHBOARD_CALLBACK_URL#access_token=<jwt> - Frontend extracts token from URL fragment and stores it locally
Admin Endpoints¶
| Method | Path | Description |
|---|---|---|
PUT |
/users/{username}/oauth/authentik |
Link an Authentik account to an existing user |
DELETE |
/users/{username}/oauth/authentik |
Unlink Authentik account from a user |
Dashboard OAuth Helpers¶
The dashboard provides login buttons, exchanges OAuth access tokens for the session cookie, and hides developer/admin UI based on scopes.
| Variable | Description |
|---|---|
IDENTITY_URL |
Internal URL for server-to-server calls (default: http://identity:8080) |
IDENTITY_PUBLIC_URL |
Public URL used for browser redirects during OAuth/OIDC |
DEVELOPER_PORTAL_SCOPE |
Required scope for API explorer access (default: meshflows:developer:portal) |
Provider Discovery¶
GET /auth/providers on the identity service returns enabled auth providers and optional registration URLs. The dashboard proxies this via GET /api/auth/providers and uses it to show/hide Authentik/Google buttons.
Developer Portal Access¶
Users in the developers group receive the meshflows:developer:portal scope and can access the API explorer and developer-only sections in the dashboard. Admin-only navigation remains hidden for non-admins.
User & Group Administration (Admin)¶
User, group, and permission management is provided by the identity service (admin-only) and surfaced in the dashboard Access page for admins. The API remains available for automation and troubleshooting.
Create a group¶
curl -s -X POST http://identity:8080/groups \
-H "Authorization: Bearer <admin-jwt>" \
-H "Content-Type: application/json" \
-d '{"name":"testers"}'
Create a user (with groups)¶
curl -s -X POST http://identity:8080/users \
-H "Authorization: Bearer <admin-jwt>" \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"secret","email":"alice@example.com","groups":["testers"]}'
Update groups for a user¶
curl -s -X PUT http://identity:8080/users/alice/groups \
-H "Authorization: Bearer <admin-jwt>" \
-H "Content-Type: application/json" \
-d '{"groups":["developers"]}'
Set explicit permissions (direct grants)¶
GET returns { "direct", "from_groups", "effective" }. PUT replaces direct grants only; role inheritance stays on groups.
curl -s http://identity:8080/users/alice/permissions \
-H "Authorization: Bearer <admin-jwt>"
curl -s -X PUT http://identity:8080/users/alice/permissions \
-H "Authorization: Bearer <admin-jwt>" \
-H "Content-Type: application/json" \
-d '{"permissions":["meshflows:workflow:run:minimal"]}'
Set role (group) permissions¶
curl -s -X PUT http://identity:8080/groups/operators/permissions \
-H "Authorization: Bearer <admin-jwt>" \
-H "Content-Type: application/json" \
-d '{"permissions":["meshflows:workflow:run:*","meshflows:workflow:retrigger:*"]}'
See ADR 0010 and IAM role templates.
Two-factor authentication (2FA)¶
2FA is optional. Users are never forced to enable TOTP or email recovery. Login with username and password works for all accounts that have not enabled 2FA themselves.
When a user has enabled TOTP and/or email recovery, the next login step requires that second factor (mfa_required in the login response).
| Variable | Default | Description |
|---|---|---|
IDENTITY_MFA_ENABLED |
true |
When false, MFA setup and verification are disabled platform-wide |
User self-service (Profile in dashboard): TOTP setup, email recovery, recovery codes.
Admin (requires meshflows:iam:manage):
| Method | Path | Description |
|---|---|---|
GET |
/users/{username}/mfa |
Read TOTP / email recovery status |
POST |
/users/{username}/mfa/reset |
Clear 2FA for a user (lost device); user can set up again under Profile |
There is no platform-wide “enforce 2FA for everyone” flag in Phase 3.
Orchestrator Invocation Modes¶
HTTP-triggered workflows¶
- OAuth2/JWT scope validation when enabled.
- Optional bearer token fallback:
- Global:
HTTP_INVOCATION_TOKEN - Per workflow:
WORKFLOW_HTTP_TOKENS
Scheduled workflows¶
SCHEDULE_INVOCATION_TOKENfor scheduler/internal invocation.- Optional OAuth2 scope enforcement with scheduled auth mode.
Admin operations¶
X-Reload-Tokenfor validate/reload control endpoints.
Recommended Baseline¶
- Use JWT/OAuth2 for primary auth; keep shared tokens only as compatibility fallback.
- Use API keys for CI pipelines and system integrations.
- Restrict Google OAuth to your own domain(s) via
IDENTITY_GOOGLE_ALLOWED_DOMAINS. - Rotate admin and invocation tokens periodically.
- Avoid exposing internal admin routes publicly.
- Enforce least privilege; use
required_scopeson gateway routes.