Skip to content

authentik: move login and role management to Slack - #1037

Merged
sbee-mq[bot] merged 12 commits into
mainfrom
slack
Nov 13, 2026
Merged

sbee-mq[bot] merged 12 commits into
mainfrom
slack

Conversation

@mulatta

@mulatta mulatta commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

Move lab sign-in and role management to Slack so routine access changes no longer require Terraform commits or duplicate identities.

  • Replace Google and password sign-in with Slack. Allow SBEE Lab workspace members to enroll into sjanglab-pending, with no application access until granted a role.
  • Remove people from Terraform management. Sync researcher, student, and staff roles from Slack user groups, and propagate Slack deactivation with removal safeguards. Keep admin membership outside sync and preserve break-glass access.
  • Make application access visible through group bindings and simplify Headscale ACLs.
  • Run role sync over outbound-only connections, with event-driven reconciliation and polling for newly enrolled accounts.
  • Add Quorum OIDC, bot, and test-driver apps; remove the obsolete slack-index app.

Validation: package build, TypeScript typecheck, 13 tests, changed-file formatting/lint checks, and git diff --check passed. Live-service integration was not tested.

@mulatta
mulatta force-pushed the slack branch 3 times, most recently from 9746d4b to 5a1d871 Compare November 9, 2026 07:09
Everyone already has an account in the lab's Slack workspace, while Google accounts and local passwords were a second identity to keep in step with it. The login page now shows only a Slack button, and a Slack identity signs in only when it is linked to an account.
Authentik's own "slack" source type sends the OIDC scopes to Slack's app installation endpoint, which rejects them, so the source uses generic OpenID Connect. Replacing the source would delete every link, hence prevent_destroy. `ak create_recovery_key` on the authentik host remains the way in when Slack is unavailable.
Researchers and students differed only on tag:ai, which serves nothing since MULTI-evolve and the document services were retired. Headscale admits a login only after Authentik's allowed_groups check, so every member is already approved; listing people again in the policy only tied it to the user inventory. Admins stay listed for the monitoring and nix-grpc ports, and unauthenticated services go behind Authentik forward auth rather than the ACL.
The authentik API token that the sync service replaced by this policy left in modules/headscale/secrets.yaml is removed; nothing reads it.
Access was a set of expression policies whose group lists only the code showed. Group bindings put the allowed groups on each application's page in the UI, and the rules now live in one map in terraform/authentik/access.tf.
Staff covers administrative work outside research. Pending holds accounts without a role yet, and opens nothing.
The lab has one infrastructure admin, who works in the UI, and its owner does not read code, so routine changes to people should not need a commit. Terraform keeps the structure and the two accounts the infrastructure depends on: terraform owns the API token this configuration uses, and akadmin is the break-glass target; prevent_destroy protects both. The student expiry check and the inventory's sops rule go with the inventory.
The people were taken out of the state before this change, so applying it removes no account.
quorum's MCP server limits each request to the Slack channels its caller belongs to, so the token carries the caller's Slack member id, read from their Slack connection; without one the claim is absent and nothing is visible. The client is public because MCP clients run on people's machines and listen on a loopback port of their choosing.
2026.5.0 reads a role's permissions back right after assigning one and fails with "permission not found" when the new permission is not listed yet, leaving the resource tainted. 2026.8.2 carries the upstream fix (f175a425) and matches the 2026.8 server.
Keeps Authentik's researchers, students and staff groups equal to the Slack user groups of the same role. Each reconcile reads both sides whole and applies the difference, so a missed Socket Mode event costs only latency: it reconciles after every connect, shortly after a group or user event, three times a day, and with backoff after a failure.
It changes nothing when a mapped Slack group is missing, when a removal exceeds the larger of 3 and 30% of synced accounts, or when a synced group was last edited by someone who is not a Slack admin. It never touches accounts in sjanglab-admins and reactivates only accounts it deactivated itself.
Access is now granted and revoked by editing Slack user groups, where the lab already keeps its roles, instead of in the Authentik UI. The sync runs on eta beside Authentik and reaches its API over loopback; Slack events arrive over Socket Mode on the login app, which gains a bot with read-only scopes, so no inbound port is opened. Its health reaches Gatus as platform / Slack group sync.
The service account may change membership only in the researchers, students, staff and pending groups, so it cannot grant admin. Authentik 2026.8 takes these object permissions by full name.
New people no longer need an admin to create their account and link it. A member of the lab's Slack workspace who signs in for the first time gets an account named by their Slack email, in sjanglab-pending, which opens nothing until slack-group-sync grants a role group from Slack user groups. Other workspaces are refused by policy.
Linked accounts keep signing in through the authentication flow, which has no user write stage, so enrolling changes nothing for them.
Change-Id: Ia8a29ec835beac9a9c1eb4a779c6fe85aac841d0
@mulatta
mulatta enabled auto-merge (rebase) November 13, 2026 05:43
@sbee-mq
sbee-mq Bot merged commit b77351f into main Nov 13, 2026
8 checks passed
@sbee-mq
sbee-mq Bot deleted the slack branch November 13, 2026 05:43
@sbee-mq sbee-mq Bot added mq/waiting and removed mq/waiting labels Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant