Skip to content

Commit 5298fdc

Browse files
committed
Merge delegated Slack access settings
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
2 parents 00632ab + c259b0b commit 5298fdc

13 files changed

Lines changed: 449 additions & 51 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ product overview.
1818
1919
## Unreleased
2020

21+
- Add a manager/admin-only Access page to Slack channel settings for base mode (including Admin), Auto, Lean,
22+
network, use/manage policy, and named guest/manager lists. Recheck live membership and current
23+
roles on save; immediately acknowledge submissions while validation runs. Admin-author-only
24+
engine bypass and existing ordinary-tab access remain unchanged.
25+
2126
- Channels: use Read-only, Worker, and Admin as the three base modes, with independent Auto and
2227
Lean side toggles in channel, DM, and template editors. Slack Settings can now select Admin
2328
for authorized admins. Admin gives other members Worker plus their selected options; Auto

‎FEATURES.md‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ A categorized catalog of what's shipped. Cross-linked to `TEST-PLAN.md` checks.
5858
never has to carry a per-author sentence, and a channel with no Composio gets no line at all.
5959
→ TEST-PLAN: Composio identity and connection discovery.
6060

61-
- **Focused conversation settings:** Access presents Read-only, Worker, and Autonomous as the
62-
primary modes, with Full access and Lean as clearly separated special-mode boxes; Custom is no
61+
- **Focused conversation settings:** Access presents Read-only, Worker, and Admin as the
62+
base modes, with Auto and Lean as independent options; Custom is no
6363
longer offered. MCP Connections, Cloud MCP, Environment tokens, and Skills are separate first-class
6464
channel pages rather than nested beneath Tools; enabled skills sort first and the channel-level
6565
Grant Tier switch is gone.
6666
- **Slack settings for authorized users:** replies requested by anyone allowed to use the agent add a
67-
requester-bound **⚙️ Settings** footer button. Its four-tab Block Kit console mirrors the web
67+
requester-bound **⚙️ Settings** footer button. Its Block Kit console mirrors the web
6868
setup concepts: Engine & model can be changed by every authorized user in this console; MCP Connections
6969
rotates/removes the write-only Composio, Toolbox and Make MCP credentials plus inherited-token
7070
policy, and edits the Composio account label shared with the web setup form. Labels are shown
@@ -78,6 +78,12 @@ A categorized catalog of what's shipped. Cross-linked to `TEST-PLAN.md` checks.
7878
so historic controls cannot retain revoked access. Cloud MCP actions additionally re-check admin
7979
status. Secrets can be edited in every channel mode, including through `/secrets`; file-edit
8080
permissions and the separate `/model` command policy are unchanged.
81+
**Access** is a fifth tab, visible only to current admins/channel managers. They can edit the
82+
base mode (including Admin/full access), Auto, Lean, network, use/manage policy and named guest/manager lists. Selecting
83+
Full access does not grant anyone an administrator role; bypass still requires an admin author.
84+
Saves acknowledge immediately with a progress view, validate named users against live human
85+
channel membership, re-check management and roles at the write boundary, and audit policy changes.
86+
DMs keep the existing four tabs. Work-dir and gateway-wide settings are not exposed here.
8187
→ TEST-PLAN: Conversation settings + on-demand memory.
8288
- **Truthful guest access:** approved members appear selected because they already have access;
8389
admins are selected and locked, while explicit guest grants remain independently editable.
@@ -1363,16 +1369,16 @@ A categorized catalog of what's shipped. Cross-linked to `TEST-PLAN.md` checks.
13631369
read-only permission profile intentionally withholds command execution. → TEST-PLAN: Engines.
13641370
- The web channel editor, custom DMs, and default templates share the three-mode picker and
13651371
side toggles. The Slack reply's **Settings** button exposes Read-only/Worker/Admin plus Auto/Lean
1366-
on its Runtime tab; only current gateway admins can select Admin. Every click rechecks user
1372+
on its manager/admin-only Access tab for channels. DMs retain Runtime mode controls with
1373+
Admin selection restricted to admins. Every click rechecks user
13671374
authorization and channel membership, and every change is audited. `/mode read|worker|admin` changes the
13681375
base while preserving applicable options (`bash` remains a compatibility alias). Legacy run-API
13691376
presets remain accepted with their existing capability-reduction boundary.
13701377
- **Two-axis access model** (per channel, both editable in the admin UI): **Who can use** (`meta.access`:
13711378
Approved members / Admins only / Locked) and **Who can manage** (`meta.manageAccess`: Org admins only /
1372-
Channel members / Custom + `meta.managers[]`). A channel manager may change SAFE settings (capability
1373-
up to Autonomous, skills, connectors, the MCP allowlist) but **never** Full-access / network / work-dir —
1374-
those stay org-admin-only. Enforced in the gateway control MCP (`requireManage` vs `requireAdmin`) and
1375-
the in-thread `/mode` command; default `admins` means relaxing it is strictly opt-in. Settings →
1379+
Channel members / Custom + `meta.managers[]`). The Slack Access page delegates channel mode (including Admin), Auto, Lean, network and use/manage policy to
1380+
current managers. Work-dir stays org-admin-only. The gateway control MCP (`requireManage` vs
1381+
`requireAdmin`) and in-thread `/mode` command retain their narrower admin checks; default `admins` means relaxing it is strictly opt-in. Settings →
13761382
**Reset all channels' access to default** (confirm-gated, audit-logged) restores use/manage to defaults
13771383
and clears custom guest + manager lists, leaving capability/skills/tokens untouched.
13781384
→ TEST-PLAN: channel access model.

‎TEST-PLAN.md‎

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ pass. Many checks are manual (require a real Slack workspace + an authenticated
1515
stays. Enable Auto: Worker is selected. At wide widths options sit beside the base choices;
1616
narrow screens stack without overflow.
1717
- Slack Settings acceptance (engine-independent): as an admin fixture actor open a recent reply's
18-
Settings button, choose Admin, and toggle Auto/Lean independently. Reopen and verify persistence
19-
and the `slack-settings` audit event. A member-manager sees Read-only/Worker and both options;
20-
a forged Admin action or revoked authorization/membership grant is rejected before mutation.
18+
Settings → Access button, choose Admin, and toggle Auto/Lean independently. Reopen and verify persistence
19+
and the `slack-settings` audit event. A member-manager sees all three modes and both options; ordinary members do not see Access.
20+
Forged legacy Runtime mode actions and revoked authorization/membership grants are rejected.
21+
DMs keep Runtime mode controls with Admin restricted to admin authors.
2122
- Runtime acceptance (Claude AND Codex): in an isolated fixture set Admin + Auto + Lean. As the
2223
approved non-admin fixture actor ask "Create mode-check.txt containing MODE_OK, read it back,
2324
and reply with its contents." Pass only with matching saved bytes, no approval click/card,
@@ -138,7 +139,8 @@ a pass.
138139
Automated: `test/channel-memory.test.js`, `test/memory-search.test.js`,
139140
`test/memory-snapshot-run.test.js`, `test/channel-members-ui.test.js`,
140141
`test/access-grants.test.js`, `test/gateway-mcp-authz.test.js`,
141-
`test/mcp-control-plane-approval.test.js`, `test/channel-settings-modal.test.js`.
142+
`test/mcp-control-plane-approval.test.js`, `test/channel-settings-modal.test.js`,
143+
`test/access-settings.test.js`.
142144

143145
- [x] Large MEMORY.md and topic writes succeed without a character-capacity failure.
144146
- [x] On an engine without FTS5 (Node 22.13) the database opens, migration 17 is skipped with a warning, and `search_channel_memory` answers from the plain scan with AND semantics, diacritic folding and bracketed excerpts; `ensureMemoryFtsTable` is idempotent and creates the index the moment the engine supports it.
@@ -167,6 +169,35 @@ Automated: `test/channel-memory.test.js`, `test/memory-search.test.js`,
167169
authorization and Slack membership before every mutation. Cloud MCP is hidden from non-admins
168170
and its controls reject revoked admin status; all authorized users can edit runtime and secrets
169171
in every channel mode regardless of manager policy.
172+
- [x] Automated Access: ordinary authorized users cannot see/forge the fifth tab; admins,
173+
approved members under Members policy and named managers under Custom policy can edit it.
174+
DMs keep four tabs. Independent base-mode/Auto/Lean/network flags round-trip; preset
175+
flags and stored profile agree. Unknown fields cannot change workDir, credentials or roles.
176+
Real store saves preserve unrelated settings and audit only policy. Departed actors,
177+
outsiders/bots in named lists, revoked channel grants and global role revocation during the
178+
final membership request are rejected. Submission acknowledgment precedes asynchronous work.
179+
- [ ] Live Access UI (engine-independent Slack callback case): create disposable Slack channel
180+
`access-settings-qa`, join an admin actor, an approved member, a named external guest, and
181+
the bot. Start with Worker, network/Full access/Lean off, Approved use, Admins manage, and
182+
no explicit grants. From a fresh reply open Settings as each actor. Only admin sees Access.
183+
Change manage to Members; approved actor now sees Access, guest does not. Save Admin mode,
184+
Auto, Lean, network, named guest, and Custom management with the approved actor
185+
named. Reopen Slack and web settings: all values agree; unrelated model/tokens are unchanged;
186+
audit identifies actor/channel and contains no secrets. Clear special flags/lists and save:
187+
all clear. Try a bot and a user outside the channel: save fails without changing metadata.
188+
Revoke management or remove the actor with the editor open: old submit fails. Delay Slack
189+
membership responses beyond three seconds: immediate progress view, then one final result;
190+
no Slack timeout or double save. Restore/delete fixture. Pending live execution.
191+
- [ ] Live Access Claude and Codex (one run each in disposable channel `access-settings-qa`):
192+
select engine explicitly, Admin mode, Auto/Lean/network off, Members management.
193+
As approved non-admin, prompt “Create access-proof.txt containing access proof and report
194+
whether permission bypass is active.” As admin, repeat with a different filename. Pass when
195+
per-run launch evidence has bypass only for the admin author and both runs stay in their
196+
declared container mounts. As the non-admin actor, enable Lean and start a fresh thread: “List the connectors and
197+
skills available in this run.” Pass when runtime evidence shows the lean tool/skill policy.
198+
Toggle network and ask “Is network use allowed here?”; compare the answer and launch policy
199+
to the stored setting (advisory network is not an egress isolation claim). Restore fixture
200+
settings/files; retain launch/audit evidence. Pending live execution for both engines.
170201
- [ ] Live Claude: in `cg-testing-claude-auto`, keep Who can manage set to Admins and Apps approved
171202
but not a manager. Let Apps request a fresh reply and open **⚙️ Settings**. Pass when Apps
172203
can change to another valid engine/model/effort and restore it; cannot see or operate Cloud MCP;

‎public/app.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ const ACCESS_HELP = {
241241
none: "Locked — nobody can use the bot here until you add them by name in the Users tab (Allowed users).",
242242
};
243243
const MANAGE_HELP = {
244-
admins: "Only gateway admins can change this channel's settings (from Slack or here). (Default.)",
245-
members: "Any approved member of this channel can change the safe settings (capability up to Autonomous, skills, connectors) — but never Full access, network or work-dir.",
244+
admins: "Only gateway admins can edit the Slack Access page. Other authorized users can edit the ordinary Settings tabs. (Default.)",
245+
members: "Any approved channel member can edit Slack Access settings: Read-only/Worker/Admin mode, Auto, Lean, network, access policy and named users/managers. Permission bypass still requires an admin author. Work-dir stays admin-only.",
246246
};
247247
function channelProfileOf(m = {}) {
248248
if (m.adminMode) return "admin";

‎public/index.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ <h2 class="ch-name"></h2>
11071107
<label class="togglerow ch-network-wrap">
11081108
<input type="checkbox" class="ch-network" />
11091109
<span class="switch"></span>
1110-
<span class="t"><b>Network</b><small>tells the engine whether this channel is meant to use the network; the container itself stays on the bridge network until the egress proxy ships — needs Bash, admin-only</small></span>
1110+
<span class="t"><b>Network</b><small>tells the engine whether this channel is meant to use the network; the container itself stays on the bridge network until the egress proxy ships — editable by admins and channel managers in Slack Access settings</small></span>
11111111
</label>
11121112
</label>
11131113

‎src/config/store.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export function defaultChannelMeta({ channelId, name, type, isDM, platform }) {
181181
platform: isPlatformId(platform) ? platform : DEFAULT_PLATFORM,
182182
access: "approved", // who can USE the channel: "approved" | "admins" | "none" (set from the gateway
183183
// default at join). Governs who's auto-granted in a channel; allowedUsers is the manual override.
184-
manageAccess: "admins", // who can MANAGE (change safe settings) from Slack: "admins" | "members" | "custom".
184+
manageAccess: "admins", // who can MANAGE the Access page from Slack: "admins" | "members" | "custom".
185185
managers: [], // when manageAccess="custom": Slack user ids allowed to manage this channel.
186186
profile: isDM ? undefined : "read", // capability preset: read|worker|auto|full|lean|custom (see modes.js);
187187
// expands to the flags below on save. undefined/legacy channels derive it from the flags.

‎src/gateway/gateway-usage/references/administration.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ and friends read `SUPABASE_ACCESS_TOKEN` / `VERCEL_TOKEN` without being told to.
161161
The Slack **Settings** reply button is available to every authorized agent user, including channel
162162
guests. It allows editing engine/model/effort, channel skills and templates, MCP connection tokens
163163
and labels, and write-only secrets. Cloud MCP is visible and editable only by current admins.
164+
A separate **Access** tab is visible only to admins and current channel managers. It edits mode,
165+
Admin/full access, Auto, Lean, network, who may use/manage the channel, and named guests/managers. Manager
166+
policy applies to this entire page; changing Full access still leaves run-time bypass admin-author-only.
164167
Every interaction re-checks agent access and channel membership. This console does not grant
165168
admin rights or change the permissions required by separate gateway control tools.
166169

‎src/gateway/modes.js‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ export function authorModeMeta(meta, { isAdminAuthor = false, untrustedPrincipal
4141

4242
// Called inside the atomic settings update; changing a base mode preserves Lean and Auto.
4343
// Read-only clears Auto; enabling Auto on Read-only promotes it to Worker.
44-
export function modeSettingsPatch(current = {}, { mode, autoMode, cleanMode } = {}, { isAdminUser = false } = {}) {
44+
export function modeSettingsPatch(current = {}, { mode, autoMode, cleanMode } = {}, { isAdminUser = false, canEnableAdmin = isAdminUser } = {}) {
4545
const nextMode = mode || channelMode(current);
4646
if (!MODES.includes(nextMode)) throw new Error("Mode must be read, worker, or admin.");
47-
if (mode === "admin" && !isAdminUser) throw new Error("Only administrators can enable Admin mode.");
47+
if (mode === "admin" && !canEnableAdmin) throw new Error("Only administrators can enable Admin mode.");
4848
const patch = mode ? { ...BASE_MODE_FLAGS[nextMode], profile: nextMode } : {};
4949
if (mode === "read") patch.autoMode = false;
5050
if (typeof autoMode === "boolean") {
@@ -147,14 +147,15 @@ export function isAuthorized(meta, authorId, isDM, { isAdminUser = false, isAppr
147147
}
148148

149149
// ── Who can manage a channel ──────────────────────────────────────────────────
150-
// "Manage" = change this channel's SAFE settings (capability profile up to Autonomous, skills,
151-
// connectors) from inside Slack. Governed by meta.manageAccess (default "admins"), so existing
150+
// "Manage" authorizes the Slack Access page (mode, Full access, Lean, network, use/manage
151+
// policy and named users). Engine permission bypass still requires an admin author. Governed by
152+
// meta.manageAccess (default "admins"), so existing
152153
// channels are unchanged and relaxing it is strictly opt-in per channel:
153154
// - "admins" → gateway admins only (default)
154155
// - "members" → any approved member (membership is implied by posting in the channel)
155156
// - "custom" → only the users listed in meta.managers[]
156-
// The DANGEROUS escalations (Full-access / network / work-dir) are NEVER delegated here — the call
157-
// sites keep requiring an admin author for those. This function only answers "safe-manage?".
157+
// Individual MCP tools and /mode keep their narrower admin checks for Full access/network;
158+
// work-dir remains admin-only. Ordinary Slack Settings tabs use agent authorization separately.
158159
export function canManage(meta = {}, { authorId = "", isAdminUser = false, isApprovedUser = false } = {}) {
159160
if (isAdminUser) return true;
160161
const mode = meta.manageAccess || "admins";

0 commit comments

Comments
 (0)