Skip to content

feat: distribute Hero WARP enrollment secrets - #62

Open
xnoto wants to merge 2 commits into
mainfrom
feat/hero-host-config-warp-secret-distribution
Open

feat: distribute Hero WARP enrollment secrets#62
xnoto wants to merge 2 commits into
mainfrom
feat/hero-host-config-warp-secret-distribution

Conversation

@xnoto

@xnoto xnoto commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Add the owner-supplied encrypted SOPS entries for the dedicated Hero WARP service token and declare their narrowly scoped distribution to the private hero-host-config repository as HERO_HOST_CONFIG_WARP_CLIENT_ID and HERO_HOST_CONFIG_WARP_CLIENT_SECRET.

The Cloudflare producer already exists on applied tfroot-cloudflare main. This change does not alter the generic organization-wide Cloudflare authentication-secret broadcast.

Fixes #

None.

Type of change

  • Bug fix
  • Feature / enhancement
  • Documentation
  • Infrastructure (OpenTofu root or module)
  • GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS secrets)
  • Container image
  • CI / reusable workflow
  • Refactor / cleanup
  • Breaking change

Validation

  • Required pull-request checks pass — opentofu / test and opentofu / plan passed.
  • Centrally distributed Actions secrets are declared only through the owning OpenTofu root; no target-repository secret or workflow was hand-edited.

No local OpenTofu init, plan, apply, import, state, or secret-decryption operation was run or claimed by the agent.

Impact and rollout

Producer: tfroot-cloudflare has already applied the narrowly scoped WARP service token. This PR makes its owner-supplied encrypted values consumable by the GitHub-management root.

Consumer: after a reviewed merge and the environment-gated main apply, hero-host-config will receive exactly two Actions secrets: HERO_HOST_CONFIG_WARP_CLIENT_ID and HERO_HOST_CONFIG_WARP_CLIENT_SECRET. No other repository receives them.

Unchanged: the generic CLOUDFLARE_AUTH_CLIENT_ID and CLOUDFLARE_AUTH_CLIENT_SECRET broadcasts remain explicitly excluded from hero-host-config; no host configuration, WARP enrollment, Cloudflared migration, GitHub Actions execution, or production host mutation is included.

Delivery stages: authored, submitted, and CI-validated. Merge and the environment-gated root apply remain confirmation-gated. Secret selection in hero-host-config, workflow execution, host reconciliation, and functional verification are future stages.

Rollback: before apply, close or revert this PR. After an apply, remove the two mappings in a separate reviewed change and apply; separately rotate the Cloudflare service token if the credential must be revoked.

Safety and secrets

  • Contains only SOPS-encrypted source material and OpenTofu references; no plaintext secrets, decrypted SOPS values, state files, kubeconfigs, tokens, or private endpoints are included.
  • No local OpenTofu init/plan/apply/destroy/import/state operations were run or claimed — plans come from pull-request checks.
  • The two-secret scope, confirmation-gated apply, and rollback path are described above.

AI-assisted change: an OpenCode agent materially prepared the OpenTofu secret-distribution mapping and this pull request. The encrypted source entries were added by the owner in a trusted environment.

@xnoto
xnoto requested a review from a team as a code owner September 6, 2026 18:43
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

OpenTofu Test

OpenTofu test passed.

View the workflow run.

View run output
Terraform validate.......................................................Passed
Terraform validate with tflint...........................................Passed
Checkov..................................................................Passed
Terraform fmt............................................................Passed
Terraform docs...........................................................Passed
Detect hardcoded secrets.................................................Passed
check for case conflicts.................................................Passed
check for merge conflicts................................................Passed
check for broken symlinks............................(no files to check)Skipped
check vcs permalinks.....................................................Passed
detect destroyed symlinks................................................Passed
detect private key.......................................................Passed
fix end of files.........................................................Passed
mixed line ending........................................................Passed
trim trailing whitespace.................................................Passed
don't commit to branch..................................................Skipped
check for added large files..............................................Passed

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

OpenTofu Plan

OpenTofu plan passed.

View the workflow run.

View run output
OpenTofu will perform the following actions:

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      + created_at        = (known after apply)
      + id                = (known after apply)
      + key_id            = (known after apply)
      + plaintext_value   = (sensitive value)
      + remote_updated_at = (known after apply)
      + repository        = "hero-host-config"
      + repository_id     = (known after apply)
[REDACTED: potentially sensitive plan output]
      + updated_at        = (known after apply)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      + created_at        = (known after apply)
      + id                = (known after apply)
      + key_id            = (known after apply)
      + plaintext_value   = (sensitive value)
      + remote_updated_at = (known after apply)
      + repository        = "hero-host-config"
      + repository_id     = (known after apply)
[REDACTED: potentially sensitive plan output]
      + updated_at        = (known after apply)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

  # github_repository.repositories["tfroot-gcp"] will be updated in-place
  ~ resource "github_repository" "repositories" {
        id                                      = "tfroot-gcp"
        name                                    = "tfroot-gcp"
      ~ topics                                  = [
          + "s3-backend",
            # (7 unchanged elements hidden)
        ]
        # (36 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

  # github_repository.repositories["tfroot-twilio"] will be updated in-place
  ~ resource "github_repository" "repositories" {
        id                                      = "tfroot-twilio"
        name                                    = "tfroot-twilio"
      ~ topics                                  = [
          - "sms",
            # (4 unchanged elements hidden)
        ]
        # (36 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

Plan: 2 to add, 11 to change, 0 to destroy.
OpenTofu will perform the following actions:

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      + created_at        = (known after apply)
      + id                = (known after apply)
      + key_id            = (known after apply)
      + plaintext_value   = (sensitive value)
      + remote_updated_at = (known after apply)
      + repository        = "hero-host-config"
      + repository_id     = (known after apply)
[REDACTED: potentially sensitive plan output]
      + updated_at        = (known after apply)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      + created_at        = (known after apply)
      + id                = (known after apply)
      + key_id            = (known after apply)
      + plaintext_value   = (sensitive value)
      + remote_updated_at = (known after apply)
      + repository        = "hero-host-config"
      + repository_id     = (known after apply)
[REDACTED: potentially sensitive plan output]
      + updated_at        = (known after apply)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
[REDACTED: potentially sensitive plan output]
      ~ plaintext_value   = (sensitive value)
        # (7 unchanged attributes hidden)
    }

  # github_repository.repositories["tfroot-gcp"] will be updated in-place
  ~ resource "github_repository" "repositories" {
        id                                      = "tfroot-gcp"
        name                                    = "tfroot-gcp"
      ~ topics                                  = [
          + "s3-backend",
            # (7 unchanged elements hidden)
        ]
        # (36 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

  # github_repository.repositories["tfroot-twilio"] will be updated in-place
  ~ resource "github_repository" "repositories" {
        id                                      = "tfroot-twilio"
        name                                    = "tfroot-twilio"
      ~ topics                                  = [
          - "sms",
            # (4 unchanged elements hidden)
        ]
        # (36 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

Plan: 2 to add, 11 to change, 0 to destroy.

xnoto added a commit that referenced this pull request Sep 6, 2026
## Summary

Carry forward the exact owner-authored, SOPS-encrypted Hero WARP
enrollment entries from `chore/hero-host-config-warp-secret-source`
without reading, decrypting, or changing their ciphertext.

This is split from conflicted PR #62 because current `main` refactored
the non-secret catalog from `main.tf` into `secrets.tf`. A follow-up PR
will add the two non-secret distribution references after these
encrypted fields are present on `main`.

Fixes #

None.

## Type of change

- [ ] Bug fix
- [ ] Feature / enhancement
- [ ] Documentation
- [x] Infrastructure (OpenTofu root or module)
- [ ] GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS
secrets)
- [ ] Container image
- [ ] CI / reusable workflow
- [ ] Refactor / cleanup
- [ ] Breaking change

## Validation

- [ ] Required pull-request checks pass — pending: `opentofu / test` and
`opentofu / plan` are the validation authority.
- [x] No target repository file, Actions secret distribution, or
workflow was changed; this PR preserves the owner-authored encrypted
source file exactly.

No local OpenTofu init, plan, apply, import, state, or secret-decryption
operation was run or claimed by the agent.

## Impact and rollout

**Producer:** this PR changes only the canonical SOPS-encrypted source
file in `tfroot-github`.

**Consumer:** none until a separate reviewed change adds the
`secrets.tf` mappings and a later environment-gated apply runs. It does
not distribute a GitHub Actions secret, alter Cloudflare Access, enroll
WARP, execute a workflow, or mutate Hero.

**Delivery stages:** authored and submitted. Pull-request CI is
automatic and pending. Merge remains confirmation-gated; a main apply is
a separate confirmation-gated live mutation.

**Rollback:** close or revert this PR before any apply. The SOPS source
remains encrypted throughout.

## Safety and secrets

- [x] Contains only already-encrypted SOPS ciphertext; no plaintext
secrets, decrypted SOPS values, state files, kubeconfigs, tokens, or
private endpoints are present.
- [x] No local OpenTofu init/plan/apply/destroy/import/state operations
were run or claimed — plans come from pull-request checks.
- [x] No live system is changed by this PR; merge and any future main
apply are separately gated.

AI-assisted change: an OpenCode agent created this replacement pull
request without retrieving or changing the encrypted source material.
@xnoto xnoto mentioned this pull request Sep 9, 2026
14 tasks
xnoto added a commit that referenced this pull request Sep 9, 2026
## Summary

Distribute the existing owner-designated encrypted SSH identity from
`tfroot-github` to `hero-host-config` under the two exact secret names
consumed by its manual check-only workflow:

- `HERO_HOST_CONFIG_SSH_PRIVATE_KEY`
- `HERO_HOST_CONFIG_SSH_KNOWN_HOSTS`

The source fields and existing `tfroot-libvirt` recipients are
unchanged. No SOPS ciphertext is read, changed, or decrypted.

Fixes #

None.

## Type of change

- [ ] Bug fix
- [x] Feature / enhancement
- [ ] Documentation
- [x] Infrastructure (OpenTofu root or module)
- [ ] GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS
secrets)
- [ ] Container image
- [ ] CI / reusable workflow
- [ ] Refactor / cleanup
- [ ] Breaking change

## Validation

- [ ] Required pull-request checks pass — pending `opentofu / test` and
`opentofu / plan`.
- [x] Generated or centrally distributed files were regenerated by their
owning automation, not hand-edited — not applicable; this is the
canonical central distribution declaration and no target-repository file
was edited.
- Infrastructure-security review found no Critical, High, or Medium
findings.
- Release review verified the net diff is restricted to the two intended
Hero mappings, source fields remain unchanged, and the consumer workflow
references the exact destination names.
- No local OpenTofu init, plan, apply, destroy, import, state operation,
or secret decryption was run or claimed.

## Impact and rollout

**Producer:** `tfroot-github` is the canonical owner of the
encrypted-source reference and GitHub Actions secret distribution.

**Consumer:** after PR merge and the separate environment-gated `main`
apply, `hero-host-config` will receive the two named secrets for its
existing manual WARP/Ansible **check-only** workflow. Its existing
`tfroot-libvirt` recipients remain unchanged.

**Unchanged:** no SOPS ciphertext, secret value, Cloudflare policy, WARP
enrollment, repository workflow, public-key authorization, Hero host
configuration, Node Exporter, firewall, GitOps desired state, or
workflow dispatch is included.

**Delivery stages:** authored and submitted; PR validation is pending.
Merge and the main apply are separate explicit confirmation gates. Hero
public-key authorization and check-workflow dispatch remain separate
operations after a successful apply.

**Known follow-up:** stale PR
[#62](#62),
superseded by merged WARP PRs #63 and #64, remains open and should be
closed through a separately authorized cleanup action; it is not part of
this change.

**Rollback:** close or revert this PR before apply. After apply, remove
the two mappings through a reviewed PR and environment-gated apply;
rotate the SSH identity separately if revocation is required.

## Safety and secrets

- [x] Contains no plaintext secrets, decrypted SOPS values, state files,
kubeconfigs, tokens, or private endpoints.
- [x] No local OpenTofu init/plan/apply/destroy/import/state operations
were run or claimed — plans come from pull-request checks.
- [x] Breaking or irreversible effects are described above with rollback
notes.

AI-assisted change: an OpenCode agent added only non-secret mappings
after the owner confirmed the existing `tfroot-libvirt` SSH identity is
the intended Hero identity.
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