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.

After registering your binary, it starts with no permissions. You control exactly which OS keychain service namespaces your tool can access — and in what ways — by editing its entry in ~/.config/keychain-auth/config.json. This page explains the permission fields, the scope rules the daemon enforces, and two architectural patterns for structuring your namespaces.

Permission fields in config.json

Each registered binary has three permission fields:
  • allowed_read_services — array of service namespace strings the binary can read from.
  • allowed_write_services — array of service namespace strings the binary can write to and delete from.
  • can_search — boolean that enables search operations and prefix-based bulk reads and deletes.
A binary with all fields at their default empty/false values looks like this:
{
  "path": "/usr/local/bin/your-tool",
  "hash": "sha256:fd7ecae9159e6f93a25178d3489fbffa7219917ca12567d5e42b156948",
  "allowed_read_services": [],
  "allowed_write_services": [],
  "can_search": false
}

Permission scopes

The daemon enforces the following rules before executing any keychain operation:
  • Read — the requested service must be listed in allowed_read_services.
  • Write — the requested service must be listed in allowed_write_services.
  • Delete — the requested service must be listed in allowed_write_services. Delete is treated as a write-level privilege.
  • Search — requires can_search: true AND the requested service must be in allowed_read_services.
  • Prefix read ("match": "prefix" with "action": "read") — requires the service in allowed_read_services AND can_search: true, because the daemon must enumerate keys to resolve the prefix.
  • Prefix delete ("match": "prefix" with "action": "delete") — requires the service in allowed_write_services AND can_search: true.
All checks are pre-flight and all-or-nothing. If your tool requests five targets and any single one is unauthorized, the entire batch is rejected before any keychain operation occurs.

Architectural patterns

There are two common approaches to structuring service namespace permissions. The right choice depends on whether your tool needs to share credentials with other CLI tools.
Use direct, well-known service names (such as aws, openai, or github) when your tool needs to read or write secrets that other ecosystem CLIs also use. This allows interoperability: a secret written by your tool under the aws namespace can be read directly by the standard aws-cli, and vice versa.Edit your tool’s config.json entry:
{
  "path": "/usr/local/bin/your-tool",
  "hash": "sha256:fd7ecae9159e6f93a25178d3489fbffa7219917ca12567d5e42b156948",
  "allowed_read_services": ["openai", "aws", "github"],
  "allowed_write_services": ["openai", "aws", "github"],
  "can_search": true
}
With this configuration, your tool can read and write secrets in the openai, aws, and github namespaces, and can search or prefix-read within them.
Use Pattern A when you are building a credential manager or orchestration tool that intentionally bridges multiple CLI ecosystems.

Denied requests

If your tool attempts to access a namespace it is not authorized for, the daemon returns a denial response with a reason field explaining the rejection:
{
  "type": "RESPONSE",
  "status": "denied",
  "reason": "service_not_allowed"
}
The most common reason codes you will encounter:
  • service_not_allowed — the service namespace is not in the binary’s read or write list.
  • action_not_in_policy — the binary attempted a search or prefix operation but can_search is false.
  • unregistered_binary_pending_approval — the binary’s hash does not match any entry in config.json.