Keep the scope narrow
If an external system only writes tasks, do not grant delete and member invite. Ontra stores the permission list on the key record; you can narrow later, widening needs a new key. `api_keys.manage` is a role grant, not every member’s job. “We’ll wire everything with one key” becomes a leak in six months. An external scheduler lives on `tasks.write`. Pulling the member list is a different key.
Name the key; do not leave it as “test.” Revoke unused keys. A separate, narrow key for CI. Logs show which key ran when. A lost key is rotated; the old one drops immediately. The create screen shows the secret once. The screenshot is not pasted into a wiki. The value goes to a secret store, not to chat.
- Do not grant delete and invite to an external system
- Do not leave the key named “test”
- A lost key is rotated; the old one drops
- Logs show which key ran when
- A separate, narrow, named key for CI
Integration scenarios
If a night job writes open tasks to an external ERP, read plus narrow write is enough. If a chat bot opens cards, `tasks.create` is enough; there is no project delete. Pulling a report into external BI is a key limited to `reports.read`, not admin. Each scenario wants its own key. A shared “integration admin” is blunt access in API form.
A key is reviewed like a seat: whose, what for, still needed? Unused keys drop in the quarterly audit. Rotating a leaked key is a runbook, not heroism. You do not save a workspace by “rebuilding everything”; narrow scope shrinks the blast radius. That is why widening needs a new key — inflating the old value is easy, taking it back is hard.
Where not to put the secret
Repo, wiki, Slack, screenshot, email, a “temporary” note. None of these is a secret store. A CI variable, a vault, an env file that does not enter git. The key is shown once because a second showing becomes a habit. Whoever loses it rotates. This rule does not punish people; it shrinks the leak surface.
A key inventory and blast radius
Each integration wants its own key. A night job writing tasks to ERP needs narrow write. A chat bot opening cards needs `tasks.create`. BI pulling a report needs `reports.read`. A shared “integration admin” is blunt access in API form. `api_keys.manage` is not every member’s job. Widening needs a new key; inflating the old value is easy, taking it back is hard. Narrow scope shrinks blast radius. You do not save a workspace by rebuilding everything.
The create screen shows the secret once. The screenshot is not pasted into a wiki. The value goes to a vault, not Slack. The name is not left as “test.” CI is a separate, narrow, named key. Logs show which key ran when. A loss is rotated, the old drops. Quarterly pass: whose, what for, still needed? Unused is revoked. Repo, email, a “temporary note” are not a secret store.
Rotating a leaked key is a runbook, not heroism. First: drop the old key. Second: mint a new one even narrower. Third: read last uses in the log. Fourth: clean where the secret landed (repo, chat, screen). Fifth: write “why was everything wired to one key?” into the quarter. Keep the scope policy written so it does not repeat.
The life cycle of a key
Each integration wants its own key. An ERP night job gets narrow write. A bot gets tasks.create. BI gets reports.read. Integration admin is blunt access in API form. api_keys.manage is not every member’s job. Widening needs a new key. Narrow scope shrinks radius. You cannot save yourselves by rebuilding everything.
The secret is shown once. It is not pasted into a wiki. It goes to a vault. The name is not test. CI is a separate narrow named key. The log shows when. A loss is rotated the old drops. Quarter: whose what for still needed. Unused revoked. Repo email temporary note are not a secret store.
Leak runbook: drop the old, mint a narrower new, read the log, clean where it landed, write why was everything on one key into the quarter. Keep the policy written. Do not grant delete and invite to an external system.
A key is reviewed like a seat. A forgotten test key runs in production six months later. A forgotten intern seat leaves a grant too. They are the same discipline. The quarterly pass asks both.
An integration scenario
If an external scheduler only writes tasks, `tasks.write` is enough. Pulling the member list is a different key. “We’ll wire everything with one key” becomes a leak in six months.
More posts
Product
When tasks and docs share one record, work stops scattering
List, board, and roadmap are views of the same record. A decision is made once and every surface shows the same truth. This piece explains how a pile of tools delays delivery and how Ontra binds one record.
Security
Fine-grained access lets the team breathe
Not everyone needs every project. Add project, folder, and list access on top of roles, and privacy becomes the default. In agencies and holdings the leak is rarely malice — it is the oversized shortcut “admins see everything.”
Setup
Finish the workspace in the 7-day demo, not the tool tour
No credit card. When the demo ends the app locks and data stays. Load real work in week one instead of touring screens: a project, roles, the live sprint, the docs tree, and the first report. A showroom tour does not pick a tool; a sitting record does.
