Skip to content

RFC: Optional synced source for Slack allowed_users #1109

@antigenius0910

Description

@antigenius0910

Proposal

Problem

[slack].allowed_users is currently a static list in TOML / ConfigMap. In orgs where the canonical "who can use this bot" lives in an IdP group (Okta, Azure AD, LDAP, etc.) or other external directory, keeping that list in sync by hand is tedious and drifts.

This RFC proposes a minimal opt-in hook so operators can point openab at an externally-managed list, while keeping openab core IdP-agnostic. Slack only for this RFC; other platforms can adopt the same pattern in follow-ups if their communities want it.

Proposed shape

Add two new optional fields to [slack], mutually exclusive with the existing inline allowed_users:

[slack]
# Mode A — inline static list (existing, unchanged)
allowed_users = ["U1", "U2"]

# Mode B — externally-managed file
synced_allowed_users_path = "/etc/openab/sync/allowed_users.toml"
synced_allowed_users_stale_after = "1h"   # optional, default 1h

Setting both is a config-load error. allow_all_users = true still bypasses both.

External file format reuses the same allowed_users key so syncers don't have to learn a second schema:

# Managed by an external syncer; do not edit by hand.
# Generated: 2026-06-14T08:21:00Z
allowed_users = ["U0AB", "U0CD"]

Key behaviour

  • Reload: the file is watched (matching openab's existing usercron reload pattern); atomic swap on change.
  • Stale detection: if file mtime > synced_allowed_users_stale_after, existing sessions keep going but new sessions are refused — prevents an IdP outage from instantly locking everyone out while staying fail-closed for new traffic.
  • Read failure / malformed file: keep last-known-good; never silently degrade to empty.
  • Empty list is legitimate (group was emptied) and is applied as-is.

Reference syncer (out of openab core)

A reference Okta-Groups → file syncer is the obvious first consumer of this contract. Small (~few-hundred-LOC) single-purpose binary; runs as a sidecar in openab's Pod or as a separate Deployment / CronJob; reads Okta group members, resolves emails → Slack IDs via users.lookupByEmail, writes the file atomically.

This syncer lives outside openab core to keep openab IdP-agnostic. Any syncer (Azure AD, LDAP, CMDB, even a static CSV upload) that produces a compliant file works.

Open question for maintainers: would you prefer the reference Okta syncer to live (a) in a small new repo under the openab org, (b) as a sub-component of an existing repo, or (c) under a community / personal org with a docs link? Happy with any direction.

Open questions

  1. notify-based file-watch vs polling — would like to match whatever usercron does today for consistency.
  2. File format: TOML (consistent with the rest of openab) vs newline-delimited (simpler for syncers). Recommending TOML.
  3. Stale-threshold default: 1h reasonable for IdP syncs that run every 5–15min.
  4. Should Slack allowed_channels get the same treatment in a follow-up RFC? Same shape, but explicitly out of scope here to keep this one small.
  5. Reference syncer home (see above).

Feedback welcome on the contract shape, mutual-exclusion semantics, failure modes, and reference-syncer placement. Happy to iterate before any implementation work.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions