PRD 0048: SSH deploy-key provisioning #170

Merged
didericis merged 4 commits from prd/0048-ssh-deploy-key-provisioning into main 2026-06-03 11:58:39 -04:00
Collaborator

Closes #169.

PRD: docs/prds/0048-ssh-deploy-key-provisioning.md

Summary

  • Introduces bot_bottle/contrib/ as the package for platform-specific provisioners; core defines the DeployKeyProvisioner ABC, contrib sub-packages provide concrete implementations
  • First contrib sub-package: bot_bottle/contrib/gitea/ with GiteaDeployKeyProvisioner — generates ed25519 keypairs via ssh-keygen, registers/revokes via the Gitea deploy-key HTTP API
  • Adds deploy_key: as an alternative to identity: in git-gate.repos entries (mutually exclusive; parser rejects both-or-neither)
  • At prepare time the provisioner registers a fresh key and hands the private key to git-gate as if it were a static identity file; at teardown it deletes the key (best-effort, non-fatal)

Changes (1 commit)

  • docs/prd: add SSH deploy-key provisioning plan (PRD 0048)
Closes #169. PRD: [docs/prds/0048-ssh-deploy-key-provisioning.md](https://gitea.dideric.is/didericis/bot-bottle/src/commit/62ccf217784320d5c1376638d2a4a465920a9352/docs/prds/0048-ssh-deploy-key-provisioning.md) ## Summary - Introduces `bot_bottle/contrib/` as the package for platform-specific provisioners; core defines the `DeployKeyProvisioner` ABC, contrib sub-packages provide concrete implementations - First contrib sub-package: `bot_bottle/contrib/gitea/` with `GiteaDeployKeyProvisioner` — generates ed25519 keypairs via `ssh-keygen`, registers/revokes via the Gitea deploy-key HTTP API - Adds `deploy_key:` as an alternative to `identity:` in `git-gate.repos` entries (mutually exclusive; parser rejects both-or-neither) - At prepare time the provisioner registers a fresh key and hands the private key to git-gate as if it were a static identity file; at teardown it deletes the key (best-effort, non-fatal) ## Changes (1 commit) - `docs/prd`: add SSH deploy-key provisioning plan (PRD 0048)
Owner

Couple tweaks:

  • Would like deploy_key renamed to provisioned_key
  • Would like a failure to revoke a deployed key on cleanup to halt the cleanup and fail loudly
Couple tweaks: - Would like `deploy_key` renamed to `provisioned_key` - Would like a failure to revoke a deployed key on cleanup to halt the cleanup and fail loudly
didericis added 2 commits 2026-06-03 11:33:38 -04:00
Introduces the design for short-lived deploy keys provisioned at spin-up
and revoked at teardown, plus the contrib package structure for
platform-specific provisioner implementations. First contrib provider
targets the Gitea deploy-key API.

Closes #169
docs(prd): address review feedback on PRD 0048
test / unit (pull_request) Successful in 40s
test / integration (pull_request) Successful in 54s
fb64c50276
- Rename deploy_key → provisioned_key throughout (manifest key,
  dataclass names, internal field names, test descriptions)
- Revocation failure at teardown now halts cleanup and propagates
  loudly; a stranded key is a security concern that must surface
didericis force-pushed prd/0048-ssh-deploy-key-provisioning from f600e1fbc9 to fb64c50276 2026-06-03 11:33:38 -04:00 Compare
didericis added 2 commits 2026-06-03 11:56:41 -04:00
- manifest_git.py: add ProvisionedKeyConfig dataclass; extend GitEntry
  with ProvisionedKey field (optional); make IdentityFile default to ""
  so provisioned_key entries can be constructed without a static path;
  add _parse_provisioned_key_config; update from_repos_entry to accept
  provisioned_key as an alternative to identity (mutually exclusive,
  parser rejects both-or-neither)

- deploy_key_provisioner.py (new): DeployKeyProvisioner ABC with create()
  and delete() abstract methods; get_provisioner() factory with lazy
  contrib import for gitea

- contrib/gitea/deploy_key_provisioner.py (new): GiteaDeployKeyProvisioner
  generating ed25519 keypairs via ssh-keygen and managing them through
  the Gitea deploy-key API (POST/DELETE); 404 on delete is success;
  all other errors raise RuntimeError

- git_gate.py: add _provision_dynamic_key() called in GitGate.prepare()
  for entries with ProvisionedKey — generates key, writes private key
  and key ID files to stage_dir, patches GitGateUpstream.identity_file;
  add revoke_git_gate_provisioned_keys() for teardown — raises on failure

- docker/launch.py: call revoke_git_gate_provisioned_keys() in teardown()
  after stack.close() so revocation runs after containers stop and
  failures propagate (not suppressed)

- smolmachines/launch.py: extract _teardown_smolmachines() helper that
  catches stack.close() errors (warn + re-raise) then calls revocation;
  same fatal-on-failure contract as docker backend

- test_manifest_git.py: 9 new cases for provisioned_key parsing
- test_deploy_key_provisioner.py (new): factory smoke tests
- test_contrib_gitea_deploy_key.py (new): create/delete/error/split tests

Closes #169
docs(prd): activate PRD 0048 — SSH deploy-key provisioning
test / unit (pull_request) Successful in 37s
test / integration (pull_request) Successful in 41s
6a16f7753f
didericis merged commit 83463f1cc8 into main 2026-06-03 11:58:39 -04:00
didericis deleted branch prd/0048-ssh-deploy-key-provisioning 2026-06-03 11:58:39 -04:00
Sign in to join this conversation.