Skip to main content

Documentation Index

Fetch the complete documentation index at: https://theseventeen-2abbdf80.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Native OS keychains (macOS Keychain, Linux Secret Service, Windows Credential Manager) index credentials using exactly two fields: a service name and an account name (also called the target). They have no native concept of folders, projects, environments, or workspaces. If your CLI tool manages secrets for multiple tenants, projects, or deployment environments, you need a strategy that works within this flat structure. The recommended approach is to encode all tenant context directly into the target field using a hierarchical string prefix. This requires no platform-specific code and works identically on macOS, Linux, and Windows.

Why prefix encoding works

Because keychain-auth mediates all keychain access and supports prefix-based queries, you can treat the target field as a path-like identifier. The daemon performs all filtering server-side, so you never need to fetch large credential sets and filter them in client memory. Two common formats:
[project_id]:[environment]:[secret_name]
proj_123:production:DATABASE_URL

[environment]/[workspace_id]/[project_id]/[secret_name]
production/workspace_abc/proj_123/OPENAI_API_KEY
Choose a delimiter (: or /) and apply it consistently across all writes from your tool.

Write, read, and prefix read examples

{
  "type": "REQUEST",
  "action": "write",
  "service": "your-tool",
  "targets": ["production/workspace_abc/proj_123/OPENAI_API_KEY"],
  "values": ["sk-proj-456"]
}
The prefix read returns all matching targets and their plaintext values in a single round-trip:
{
  "type": "RESPONSE",
  "status": "success",
  "results": [
    {
      "target": "production/workspace_abc/proj_123/OPENAI_API_KEY",
      "value": "sk-proj-456"
    },
    {
      "target": "production/workspace_abc/proj_123/AWS_SECRET_KEY",
      "value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    }
  ]
}
Prefix reads require can_search: true in your binary’s config.json entry, in addition to the service being listed in allowed_read_services. The daemon must enumerate keys to resolve the prefix filter.
If you want to list the names of secrets matching a prefix without reading their values — for example, to show the user what secrets exist before fetching them — use a search action instead:
{
  "type": "REQUEST",
  "action": "search",
  "service": "your-tool",
  "targets": ["production/workspace_abc/proj_123/"]
}
The daemon returns only the matching target keys, with no value fields:
{
  "type": "RESPONSE",
  "status": "success",
  "results": [
    { "target": "production/workspace_abc/proj_123/OPENAI_API_KEY" },
    { "target": "production/workspace_abc/proj_123/AWS_SECRET_KEY" }
  ]
}
You can then follow up with explicit read requests for only the specific secrets your tool needs. This two-step pattern minimizes the number of plaintext values held in memory at any time and generates more granular entries in the daemon’s audit log.

Bulk deletion with prefix matching

The same prefix matching works for delete operations, making it straightforward to clean up all secrets for a project or environment in a single request:
{
  "type": "REQUEST",
  "action": "delete",
  "service": "your-tool",
  "match": "prefix",
  "targets": ["production/workspace_abc/proj_123/"]
}
Prefix deletes require can_search: true AND the service in allowed_write_services, for the same reason as prefix reads: the daemon must enumerate keys to find all matches.

Choosing a prefix scheme

The format you choose is entirely up to you, but a few guidelines help keep things maintainable:
  • Put the highest-cardinality segment last (the secret name), so shorter prefixes naturally match broader sets.
  • Use a consistent delimiter throughout your tool — mixing : and / in the same target string makes prefix filtering harder to reason about.
  • Avoid embedding values that contain your delimiter character (for example, do not use a project name like proj:dev if : is your delimiter).
Start with the [project_id]:[environment]:[secret_name] format if you are organizing primarily by project, or [environment]/[workspace_id]/[project_id]/[secret_name] if environment is the primary query axis for your tool.