Skip to content

feat(registry): v0.4 Phase 2b — registry invite#51

Merged
TechAlchemistX merged 1 commit intomainfrom
feat/v0.4-registry-invite
Apr 20, 2026
Merged

feat(registry): v0.4 Phase 2b — registry invite#51
TechAlchemistX merged 1 commit intomainfrom
feat/v0.4-registry-invite

Conversation

@TechAlchemistX
Copy link
Copy Markdown
Owner

Summary

v0.4 Phase 2b lands per build-plan-v0.4: `secretenv registry invite [--registry ] [--invitee ] [--json]` — emits a copy-pasteable onboarding payload for sharing a registry with a new collaborator.

Three sections in human output:

  1. Config snippet the new user adds. Mirrors every non-`type` field from the inviter's `[backends.]` block, sorted for determinism. Strict-mock test-only fields (`aws_bin`, `vault_bin`, `op_bin`, `gcloud_bin`, `az_bin`) are filtered so production snippets never leak mock-binary paths. The snippet round-trips through `Config::from_str` — locked by a unit test.
  2. IAM/RBAC grant command the inviter runs as administrator. Hand-tuned per backend type:
    • `aws-ssm` → `aws iam attach-user-policy --policy-arn AmazonSSMReadOnlyAccess`
    • `aws-secrets` → same shape with `SecretsManagerReadWrite`
    • `1password` → `op vault user grant ...` (vault name extracted from URI path)
    • `vault` → `vault policy write` + `vault token create`
    • `gcp` → `gcloud secrets add-iam-policy-binding --role roles/secretmanager.secretAccessor`
    • `azure` → `az role assignment create --role "Key Vault Secrets User"`
    • `local` → filesystem/git guidance, no CLI grant
    • unknown → generic "no canonical template" pointer
  3. Verify steps — two universal commands (`secretenv doctor`, `secretenv registry list`).

`--invitee ` substitutes a real identifier into the grant; absent, the placeholder is `` so operators can sub it in later. `--json` emits the same `Invitation` struct as a stable JSON shape.

Tests

  • +16 unit tests in `crates/secretenv-cli/src/invite.rs`: selection error paths (URI vs Name, missing registry, missing backend instance), all 7 per-backend grant arms (incl. unknown-type fallback), config-block round-trip through `Config` loader, test-only field filtering (no `aws_bin` leak), bare-key vs needs-quoting heuristic, both human + JSON renderers.
  • +3 CLI integration tests in `tests/cli.rs`: end-to-end against the local-backend fixture (sectioned output + invitee propagation), JSON round-trip, clap `--help` discoverability lock for `--invitee` + `--json`.
  • Workspace total: 493/493 (was 474; +19). fmt + clippy `--deny warnings` (CI-style form, post-PR-feat(registry): v0.4 Phase 2a — registry history #50 lesson) + deny + audit clean.

Test plan

  • `cargo test --workspace` — 493/493 green
  • `cargo fmt --all -- --check` — clean
  • `cargo clippy --all-targets --workspace -- --deny warnings` — clean (CI-style form)
  • `cargo deny check` — `advisories ok, bans ok, licenses ok, sources ok`
  • `cargo audit` — no advisories
  • CI to confirm cross-platform parity

Out of scope

  • Live-backend integration smoke stays bundled with the v0.4 closing audit per the aggregate-release posture.
  • Auto-generating fully-resolved IAM policy documents (vs the current "starting-point grant" approach) — requires more environmental knowledge than the CLI has. Operators adapt the `` and `` placeholders.

🤖 Generated with Claude Code

Adds `secretenv registry invite [--registry <name>] [--invitee <id>]
[--json]` — emits a copy-pasteable onboarding payload for sharing a
registry with a new collaborator.

Three sections in the human output:

  1. The `config.toml` snippet the new user adds. Mirrors every
     non-`type` field from the inviter's `[backends.<instance>]`
     block, sorted for determinism. Strict-mock test-only fields
     (`aws_bin`, `vault_bin`, `op_bin`, `gcloud_bin`, `az_bin`) are
     filtered so production snippets never leak mock-binary paths.
     The snippet round-trips through `Config::from_str` — locked by
     `config_block_round_trips_through_config_loader`.

  2. The IAM/RBAC grant command the inviter runs as administrator.
     Hand-tuned per backend type:
       - aws-ssm     → aws iam attach-user-policy --policy-arn
                       AmazonSSMReadOnlyAccess
       - aws-secrets → same shape with SecretsManagerReadWrite
       - 1password   → op vault user grant ... (vault name extracted
                       from URI path)
       - vault       → vault policy write + vault token create
       - gcp         → gcloud secrets add-iam-policy-binding ...
                       --role roles/secretmanager.secretAccessor
       - azure       → az role assignment create
                       --role "Key Vault Secrets User"
       - local       → filesystem/git guidance, no CLI grant
       - unknown     → generic "no canonical template" pointer

  3. Two universal verify steps the invitee runs to confirm
     onboarding (`secretenv doctor`, `secretenv registry list`).

`--invitee <id>` substitutes a real identifier into the grant; absent,
the placeholder is `<INVITEE>` so operators can sub it in later.
`--json` emits the same `Invitation` struct as a stable JSON shape for
internal-tooling consumers.

Tests:
- 16 unit tests in `invite.rs` covering selection error paths
  (URI not Name, missing registry, missing backend instance), all 7
  per-backend grant arms (including unknown-type fallback), config-
  block round-trip through Config loader, test-only field filtering
  (no aws_bin leak), bare-key vs needs-quoting heuristic, and both
  human + JSON renderers.
- 3 CLI integration tests: end-to-end against the local-backend
  fixture (sectioned output + invitee propagation), JSON round-trip,
  and clap --help discoverability lock for --invitee + --json.

Workspace tests: 493/493 (was 474; +19). fmt + clippy + deny + audit
clean (CI-style `--all-targets --workspace -- --deny warnings` form).

Refs build-plan-v0.4 §Phase 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: TechAlchemistX <mandeep@techalchemist.io>
@TechAlchemistX TechAlchemistX merged commit 54fb25d into main Apr 20, 2026
7 checks passed
@TechAlchemistX TechAlchemistX deleted the feat/v0.4-registry-invite branch April 20, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant