Skip to content

docs(access): resource ACLs — restricting sensors and configs by scope - #394

Open
maximelb wants to merge 4 commits into
masterfrom
docs/resource-acl-user-guide
Open

docs(access): resource ACLs — restricting sensors and configs by scope#394
maximelb wants to merge 4 commits into
masterfrom
docs/resource-acl-user-guide

Conversation

@maximelb

@maximelb maximelb commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

User-facing documentation for resource ACLs. New page at docs/7-administration/access/resource-acls.md, plus a nav entry and three small edits to existing pages.

The page

Written for an administrator who wants to compartmentalise part of an organization — a mail feed with message bodies, an HR fleet, a customer covered by a separate agreement — and has to decide whether to do that with a separate org, a group, or a resource ACL.

  • The model: an acl:<scope> tag on a resource, an acl hive record listing the scope's members, and the rule that both the ordinary permission check and scope membership must pass.
  • A table of what is gated (telemetry, tasking, detections, artifacts, config record contents) against what stays visible (existence, hostname, tags, online status, counts), so nobody expects sensors to disappear from the fleet list.
  • acl.set / acl.get, which roles carry them, and a plain statement that acl.set is confidentiality-equivalent to unrestricted read while granting no implicit read.
  • Step-by-step setup with the CLI: create the scope, choose member types, tag sensors / installation keys / config records, verify — including "check with a real analyst account, not one holding acl.set".
  • Outputs: excluded by default, opt in per scope with acl_scopes, live streams inherit the opener's scopes, and the retention-output caveat.
  • D&R rule acl_scopes, the redaction marker on config records and why writing it back is refused, and the extension-API-key gotcha for restricted playbooks and configs.
  • Error-code table and a troubleshooting section.

The behaviours that surprise people

These get their own section because every one of them is counter-intuitive and at least one is a footgun:

  • Restriction follows the tags a resource carries now, so tagging a sensor hides its history and untagging re-exposes it.
  • A scope tag whose record does not exist, is disabled, or has expired locks the resource. Deleting a scope record is not how you un-restrict something — removing the tag is.
  • Scope tags cannot carry a TTL, and D&R rules cannot add or remove them.
  • Propagation is bounded at about five minutes, so removing someone from a scope is not instant revocation.

Other changes

  • acl.set / acl.get added to the permissions reference.
  • A short "reserved acl: namespace" section in Sensor Tags, since that page currently tells people tags are free-form.
  • A pointer from Designing Access, whose "groups are additive only" warning previously left "how do I take access away" unanswered.

Verification

  • Every CLI command, flag and hive name was checked against the installed limacharlie CLI (5.6.3), not from memory. The acl_scopes output parameter was traced through the SDK's form encoding to confirm a YAML list in --input-file arrives as a list.
  • markdownlint-cli2 clean; all relative links resolve.
  • No screenshots, since the flows documented here are CLI and API.

🤖 Generated with Claude Code

Adds a user-facing guide for resource ACLs: the acl: scope tag, the acl
hive scope record, what is gated (content) versus what stays visible
(existence and metadata), the acl.set / acl.get permissions and why
acl.set is admin-tier, a step-by-step setup with the CLI, and the
behaviours that surprise people — restriction follows current tags and
therefore applies retroactively to history, an unbacked or disabled or
expired scope locks rather than unlocks, scope tags cannot carry a TTL,
D&R rules cannot write them, and propagation is bounded at five minutes
so removing a member is not instant revocation.

Also covers outputs (excluded by default, opt in with acl_scopes),
D&R rule acl_scopes, the redaction marker on configuration records and
why writing it back is refused, the extension-API-key gotcha for
restricted playbooks and configs, an error-code table and a
troubleshooting section.

Adds acl.set / acl.get to the permissions reference, a nav entry, a
note on the reserved acl: namespace in Sensor Tags, and a pointer from
Designing Access, which previously had no answer for "how do I take
access away".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maximelb

maximelb commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

/lc-review

lcbill
lcbill previously approved these changes Sep 8, 2026
A verification pass against the merged implementation found several
claims that were wrong or would have misled a reader:

- D&R acl_scopes is an egress guard, not an advisory declaration. It
  decides whether `service request` / `extension request` / `start ai
  agent` may run on a restricted event, and a rule declaring nothing is
  refused on every restricted event. Also: clearing the last scope needs
  acl.set, and `dr set --detect/--respond` silently drops the field.
- The --enabled rule was stated too broadly. A create with no metadata
  flags is enabled by default; it is adding --comment/--expiry/--tag-add
  without --enabled that produces a disabled, locking scope.
- `limacharlie sync` does support the acl hive (--hive-acl, and it is in
  --all); the page previously said it did not. Replaced with the real
  caveat: pulling as a non-member captures redaction markers and the
  push back is refused.
- The web app has an ACL Scopes page; the page implied CLI only.
- acl.set is not a bypass for a temporary live stream.
- Exporting query results to an output drops every restricted record
  regardless of scopes or acl_scopes.
- Propagation bound is ~6 minutes (TTL plus fuzz), not 5.
- Error table: hive tag refusals are 400/UNAUTHORIZED, not
  401/UNAUTHORIZED_ACL_TAG; only 403 and 401 carry error_code; added the
  INVALID write-back refusals and ACL_SCOPES_UNAVAILABLE.
- A read-path resolution failure fails closed *silently*, so "sees
  nothing" has a third cause beyond a disabled scope and a typo.

Adds: searching restricted data, auditing ACL changes, infrastructure as
code, what resource ACLs do not restrict (LC operations, deletion,
billing, indicator searches), the need to tag at least one sensor, the
installation-key acl.set requirement, and that acl.set.<scope> grants
nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lcbill
lcbill previously approved these changes Sep 8, 2026
…opes

Both SDKs and the CLI support the acl hive, but ext-infrastructure builds
its sync list entry by entry and has no acl entry, so an organization
managed through that extension still needs scope records maintained
separately.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lcbill
lcbill previously approved these changes Sep 8, 2026
acl hive support in the extension is new, so the page should not assert
either state flatly. Says what happens when it is present (same
read-and-write permission rule as every other hive, so acl.get plus
acl.set) and what happens when it is not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

2 participants