Step 1 of 2 to port the NetBird rotator. Adds the netbird-key binary mode; the manifest port follows once CI publishes the image (the CronJob pins it by digest).
What it does
Mints a fresh reusable setup key via POST /api/setup-keys and patches it into OpenBao. Create-new, not roll-in-place — the old key is left to expire (ephemeral, bounded expiry), so nothing is deleted.
It deliberately does not delete old keys. A past manual cleanup that filtered keys for deletion wiped two unrelated ones (a jq precedence bug); that risk has no place in an automated rotator. Old keys age out on their own.
key stored verbatim (serde_json, no trailing newline)
assert_fields_exist guards the target path
an error that echoes the response redacts the key field so a value can't leak
Validated against real NetBird (throwaway key, zero blast radius)
TLS verifies with built-in webpki roots (no -k, no no-verify context needed)
POST /api/setup-keys (Token auth) -> response has 'key'
key: 36 chars, no trailing newline
settings: reusable, ephemeral, allow_extra_dns_labels, usage_limit 0, 1 auto_group
throwaway key deleted; 0 remaining
clippy -D warnings clean; 12 tests pass. In-cluster pieces (login, read_field, assert_fields_exist, patch_field) are the same code already proven live by the other modes.
Step 1 of 2 to port the NetBird rotator. Adds the `netbird-key` binary mode; the manifest port follows once CI publishes the image (the CronJob pins it by digest).
## What it does
Mints a fresh reusable setup key via `POST /api/setup-keys` and patches it into OpenBao. **Create-new, not roll-in-place** — the old key is left to expire (ephemeral, bounded expiry), so nothing is deleted.
**It deliberately does not delete old keys.** A past manual cleanup that filtered keys for deletion wiped two unrelated ones (a jq precedence bug); that risk has no place in an automated rotator. Old keys age out on their own.
## Faithful to the python it replaces
- auth is `Authorization: Token <pat>` — **not** Bearer
- `type`/`usage_limit` fixed (reusable, unlimited); name, expiry, ephemeral, allow_extra_dns_labels, auto_groups from env
- key stored verbatim (serde_json, no trailing newline)
- `assert_fields_exist` guards the target path
- an error that echoes the response **redacts** the `key` field so a value can't leak
## Validated against real NetBird (throwaway key, zero blast radius)
```
TLS verifies with built-in webpki roots (no -k, no no-verify context needed)
POST /api/setup-keys (Token auth) -> response has 'key'
key: 36 chars, no trailing newline
settings: reusable, ephemeral, allow_extra_dns_labels, usage_limit 0, 1 auto_group
throwaway key deleted; 0 remaining
```
`clippy -D warnings` clean; 12 tests pass. In-cluster pieces (login, read_field, assert_fields_exist, patch_field) are the same code already proven live by the other modes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Adds the mode that will replace the NetBird python rotator. Mints a fresh
reusable setup key via POST /api/setup-keys and patches it into OpenBao.
Create-new, not roll-in-place: the old key is left to expire (keys are
ephemeral with a bounded expiry), so nothing is deleted — no destructive step,
no window. This deliberately does NOT delete old keys; a past manual cleanup
that filtered keys for deletion wiped unrelated ones (a jq precedence bug), and
that risk has no place in an automated rotator.
NetBird auth is `Authorization: Token <pat>` — NOT Bearer. The key/type/
usage_limit semantics (reusable, unlimited) are fixed; name, expiry, ephemeral,
allow_extra_dns_labels and auto_groups come from the environment. The returned
key is used verbatim (serde_json, no trailing newline). assert_fields_exist
guards the target path. An error that echoes the response redacts the `key`
field so a value can never leak into logs.
Validated against the real NetBird API on a throwaway key (created then
deleted, zero blast radius): TLS verifies with the built-in webpki roots (no
no-verify context needed), POST with Token auth returns a 36-char key with no
trailing newline and the expected settings (reusable/ephemeral/usage_limit 0/
1 auto_group). clippy -D warnings clean; 12 tests pass; the in-cluster pieces
are the same code already proven live by the other modes.
No rotator uses it yet — the manifest port follows once CI publishes the image.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Step 1 of 2 to port the NetBird rotator. Adds the
netbird-keybinary mode; the manifest port follows once CI publishes the image (the CronJob pins it by digest).What it does
Mints a fresh reusable setup key via
POST /api/setup-keysand patches it into OpenBao. Create-new, not roll-in-place — the old key is left to expire (ephemeral, bounded expiry), so nothing is deleted.It deliberately does not delete old keys. A past manual cleanup that filtered keys for deletion wiped two unrelated ones (a jq precedence bug); that risk has no place in an automated rotator. Old keys age out on their own.
Faithful to the python it replaces
Authorization: Token <pat>— not Bearertype/usage_limitfixed (reusable, unlimited); name, expiry, ephemeral, allow_extra_dns_labels, auto_groups from envassert_fields_existguards the target pathkeyfield so a value can't leakValidated against real NetBird (throwaway key, zero blast radius)
clippy -D warningsclean; 12 tests pass. In-cluster pieces (login, read_field, assert_fields_exist, patch_field) are the same code already proven live by the other modes.🤖 Generated with Claude Code