reckon

Orgs & connections

Create orgs and environments, connect each tool to one environment or share it with labels, and keep credentials away from the agent.

Orgs and environments

An org is one business. Create one per business:

reckon org add acme --name "Acme Inc" --envs prod,uat,dev
reckon org list
reckon org show acme

--envs defaults to prod,uat,dev. Environments named prod or production are marked production; use --production to mark others. Org, environment and connection names use lowercase letters, digits and hyphens. The first org you add becomes the default context.

A second business on the same stack can start from the first:

reckon org add beta --like acme

This copies acme's environments and connections (provider, environment, CubeAPM labels) and writes an empty credentials file for each. Secrets, resource limits, knowledge and sessions are never copied. With --envs, connections tied to an environment the new org lacks are left out.

The context

The context is the org and environment a command works in. Set the default for your shell and for the next agent launch:

reckon use acme/prod     # org and environment
reckon use uat           # another environment of the same org
reckon status            # context, connections and their state

Inside an agent started with reckon open, the org and environment are pinned: --org or --env naming anything else is refused, so the agent cannot step into another business or environment. In your own shell, commands use --org and --env when given, then the link of the folder you are in, then the default from reckon use (saved in ~/.reckon/context). reckon open takes an <org>/<env> argument, and without one it uses the folder's link or the saved default. An unknown or missing org or environment is an error. Reckon never falls back to another environment, and a command run in one org's folder refuses another org.

Link a code folder to the business it belongs to, so commands run there (and in every folder below it) use that org and environment without flags. With --use, a tool name means the connection, and so the account, you prefer in that folder:

cd ~/code/acme/api
reckon link acme/prod --use github-acme --use aws-prod --use aws-uat
reckon run github -- pr list                             # github-acme, here and below
reckon run aws --env uat -- cloudwatch describe-alarms   # aws-uat, preferred for uat
reckon link                                              # every link; * marks this folder's
reckon unlink                                            # remove this folder's link

A link is a default, not a lock: --org and --env still win, and the deepest linked folder applies. Each tool may have one preferred connection per environment. A preferred connection that no longer exists is an error, never a fallback to another account. Agents started with reckon open keep their pin and ignore links. Watches and prepared writes keep the connection chosen when they were created, and saved sessions ignore preferences, so they read the same accounts from any folder. Links live in ~/.reckon/links.json.

Connections

A connection is one configured account of one tool. It takes one of three shapes:

ShapeFlagExample
Tied to one environment--for-env <env>Jenkins prod and uat are separate servers
Shared, with a label per environment--label <env>=<label>One CubeAPM server holds every environment
Shared, no labelsneitherSearch Console has no environments

A labelled connection serves only the environments it has a label for: in an environment without one, it is unavailable until you add a label.

reckon connect jenkins-prod --org acme --provider jenkins --for-env prod
reckon connect jenkins-uat  --org acme --provider jenkins --for-env uat
reckon connect cubeapm      --org acme --provider cubeapm --label prod=PROD --label uat=UAT
reckon connect gsc          --org acme --provider gsc
reckon connect --list       # every provider and its required settings

The agent names either a connection or a provider:

  • reckon run jenkins-uat -- ... uses that connection. A connection tied to another environment is refused.
  • reckon run jenkins -- ... picks the one Jenkins connection that applies to the active environment. If none or several apply, it fails and asks for a name.

Limit a connection to the resources one business owns, because one token often reaches several:

reckon connect github --org acme --allow repo=acme/* --allow repo=acme-labs/site
reckon connect gsc --org acme --allow site=sc-domain:acme.com
reckon connect k8s-prod --org acme --allow namespace=shop --allow namespace=shop-*
reckon connect github --org acme --allow-any      # remove the limits

Kinds per tool: GitHub repo (--repo, -R), Search Console and Bing site (--site, -s, or the connection's GSC_SITE/BWT_SITE), Kubernetes namespace (--namespace, -n), AWS region (--region or AWS_REGION). On a limited connection the target must be named and match, and Reckon fails closed: every source the tool could use counts (flags, comma lists, GH_REPO, GSC_SITE, positional sites and page URLs), and commands whose target cannot be pinned are refused there (gh search, gh api, GitHub URLs, sites list, Bing api, kubectl -A and cluster-wide kinds like namespaces and nodes, aws s3). gh runs in an empty folder so it cannot pick up a git remote. Prepared GitHub issues are checked against repo when prepared and again when applied.

Pin the account a connection must use, so a token or login from another business is caught before it is used:

reckon connect github --org acme --account acme-bot
reckon connect jira --org acme --account '*@acme.com'   # any account of a domain
reckon connect jira --org acme --account ''             # remove it

reckon verify reads the account from its live check and reports it: ok when it matches (case does not matter; * is a wildcard), wrong_account when the tool is logged in as someone else or does not say. Before a prepared write runs, reckon act apply makes the same check and refuses on a mismatch. Tools that report an account, and the field used:

ToolAccount reported
GitHublogin from gh api user
AWSAccount (the account ID) from sts get-caller-identity
JiraemailAddress, else name (Server), else accountId
Jenkinsid from whoami
Grafanathe org name from org current
Nginx Proxy Manageremail from user current
Elasticsearchcluster_name from cluster health
Search Consoleaccount saved at gsc auth login (none with a raw access token)
WhatsAppthe business account name

Remove one with reckon connect <name> --org acme --remove (its secrets file stays for you to delete). Run reckon connect again on an existing name to change it, for example to add a label: reckon connect cubeapm --org acme --label dev=DEV. A connection keeps its provider; use a new name for another tool. The org's connections are stored in ~/.reckon/orgs/acme/org.json, with no secrets:

"connections": {
  "jenkins-prod": {"provider": "jenkins", "env": "prod"},
  "jenkins-uat":  {"provider": "jenkins", "env": "uat"},
  "cubeapm":      {"provider": "cubeapm", "env_labels": {"prod": "PROD", "uat": "UAT"}},
  "gsc":          {"provider": "gsc"}
}

Credentials

reckon connect creates a credentials file for the connection, ~/.reckon/orgs/<org>/secrets/<connection>.env, with mode 0600. It lists the provider's settings:

# Settings for the jenkins-prod connection. One KEY=value per line; no shell syntax.
# Only JENKINS_* keys are accepted. This file is never shown to the agent.
# Or leave the keys empty and run: reckon login jenkins-prod
JENKINS_URL=
JENKINS_USER=
JENKINS_TOKEN=
# JENKINS_INSECURE=

Fill it in with your editor. Never paste credentials into the agent's chat.

  • Each line is a literal KEY=value. Nothing is expanded or executed, so $(...) and $VAR stay as text. Matching quotes around a value are removed.
  • Only the provider's keys are accepted (JENKINS_* for Jenkins). The settings for each tool are on its integration page.
  • The file must not be readable by other users. Reckon refuses it otherwise; fix it with chmod 600.
  • Values like replace_me, example.com or <...> count as not configured.
  • A value can point at a secret store instead of holding the secret: keychain:<item> (macOS Keychain, or secret-tool on Linux) or op://vault/item/field (restricted 1Password store). Reckon reads it only when a run needs it, and the agent's settings deny calling security, secret-tool or op read directly.
security add-generic-password -s acme-jenkins-prod -a "$USER" -w   # prompts for the token
# then, in ~/.reckon/orgs/acme/secrets/jenkins-prod.env:  JENKINS_TOKEN=keychain:acme-jenkins-prod

Credentials exported in your shell are never used, and neither are global CLI logins such as ~/.config/... or ~/.aws. A missing credential fails; it never falls back to something global.

Interactive login

For CLIs with their own login, run it yourself in a terminal instead of filling in the file:

reckon login jenkins-prod

It runs the CLI's login (jenkins login, gsc auth login, gh auth login --insecure-storage, aws configure, ...) with that connection's private config folder, ~/.reckon/orgs/<org>/config/<connection>/. A saved login counts as configured. reckon login needs a terminal, and Claude Code's settings in the org folder deny it to the agent.

Search Console and Bing keep their tokens in the OS keychain. Reckon gives those two CLIs your real home directory so the keychain works, and still keeps their config per connection. Kubernetes, the databases, Redis and Kafka have no reckon login; use the credentials file (and, for Kubernetes, a kubeconfig).

Check connections

reckon status            # local only: CLI installed, credentials present
reckon verify            # one live read per connection for this environment
reckon verify jenkins-prod
reckon doctor            # setup problems across every org

status shows each connection as ready, no_cli or no_credentials, with its label in this environment. verify is the only one that contacts your tools. It runs one cheap read per connection (each integration page lists it), prints ok, skipped with the reason, wrong_account, or the error, and exits non-zero if any check failed. Where the tool reports an account, verify shows it. Clarity's check uses one of its 10 daily export requests.

Each result goes to the org's activity log (reckon log --event verify), and status and preflight show the last one beside each connection, so ready (configured) and working are told apart. A result stops showing once the connection's settings change (labels, limits, account) or it is removed. A connection whose last check failed is also a preflight warning, so the agent asks you to fix it instead of trying it.

What a command gets

reckon run <connection-or-tool> -- <arguments> runs the CLI with:

  • A fresh environment. A short list of operating-system, locale, proxy and certificate variables, plus this one connection's settings.
  • Private state. Its own config folder (config/<connection>/), and its own home, cache, state and temp folders under runtime/<connection>/.
  • Safety switches. The CLI's read-only and no-prompt modes, no colour, no pager.
  • Argument checks. Flags that would change the target, credentials or safety mode are refused, and so are commands that log in, change local config or update the CLI. CLIs without a read-only mode accept only listed read commands. Each integration page lists the exact rules.
  • Bounds. A 60 second deadline by default (--timeout, at most 120) and an 8 MiB output cap (--max-bytes). Known secret values are redacted from the output.
ModeProviders
own: the CLI enforces read-onlygrafana, jenkins, cubeapm, elasticsearch, jira, nginxpm, gsc, bing, clarity
allowlist: only listed read commandsgithub, aws, kubernetes
approval: asks you before each runpostgres, mysql, mongodb, clickhouse, redis, kafka, kafka-rpk

Everything runs as your OS user, so these rules stop mistakes, not a hostile process. Give each connection the least-privileged account that works. Database users must be true read-only roles: that is the only barrier that denies writes on every path.