Menu

#157 feat: credential scoping — restrict secret access to 1, N, or all members

closed
nobody
None
2026-04-28
2026-04-20
Anonymous
No

Originally created by: kumaakh

Summary

Today a credential stored via credential_store_set can be used for all fleet members equally. While the user may want to keep some security boudaries, e.g a rogue machine may log all wrong password attempts as a means to steal passwords.

Add member-scoped credentials: at credential_store_set time, the caller specifies which members are allowed to resolve the credential. The fleet MCP server enforces this at resolution time and rejects any {{secure.NAME}} substitution from a member outside the allowed set.

Proposed API

```
credential_store_set name=github_pat members=fleet-dev # single member
credential_store_set name=shared_key members=fleet-dev,fleet-rev # N members
credential_store_set name=pub_token members=* # all (current default)
```

Enforcement

When {{secure.NAME}} is resolved in any tool (execute_command, register_member, etc.):

  1. Look up the credential's allowed member set
  2. Identify the calling member from the request context
  3. If the calling member is not in the allowed set → reject with a clear error:
    "Credential 'github_pat' is not accessible to member 'fleet-rev'. Allowed: fleet-dev"

Backward compatibility

Default when members is omitted: * (all members) — same as current behaviour.

Notes

  • Scope is stored alongside the credential in the encrypted store
  • credential_store_list should show the allowed members for each credential
  • credential_store_set on an existing credential name replaces the scope too
  • Member identity comes from the fleet server's request context, not from the tool caller — cannot be spoofed
  • an interesting aspect of "all" is that it is ephemeral... today you allow the secret to be accessible to all members=> that new members added tomorrow will also be able to use it due to "*" intention

Related

Tickets: #163

Discussion

  • Anonymous

    Anonymous - 2026-04-23

    Originally posted by: kumaakh

    Technical direction:

    1. Schema change (src/tools/credential-store-set.ts): add optional members param — comma-separated member names or * (default). Parse into a string array at input validation time.
    2. Store the scope alongside the encrypted credential value in src/services/credential-store.ts — the credential record already has a structure; add llowedMembers: string[] (or '*').
    3. Enforcement at resolution time: when a secure token is resolved in any tool, look up llowedMembers for the credential; check the calling member's name/ID from request context. If not in the allowed set and not *, reject with: Credential '<name>' is not accessible to member '<member>'. Allowed: <list>.</list></member></name>
    4. credential_store_list: include members column in output showing the allowed set.
    5. credential_store_set on existing name: replaces scope (documented clearly).

    The member identity must come from the fleet server's request context — not from anything the LLM passes in the prompt — to prevent spoofing. The * default preserves full backward compatibility.

     
  • Anonymous

    Anonymous - 2026-04-28

    Originally posted by: kumaakh

    Addressed in PR [#183] (sprint/session-lifecycle-oob-fix → main).

    Changes shipped: Credential scoping — secrets can be restricted to specific members via comma-separated names or wildcard.

    PR is open for testing — will be merged once testing is complete.

     

    Related

    Tickets: #183

  • Anonymous

    Anonymous - 2026-04-28

    Ticket changed by: kumaakh

    • status: open --> closed
     

Log in to post a comment.

MongoDB Logo MongoDB