Skip to content

feat: local Keychain-signed signer registry candidate - #27

Merged
abrichr merged 1 commit into
mainfrom
agent/lifecycle-app-prep
Sep 2, 2026
Merged

feat: local Keychain-signed signer registry candidate#27
abrichr merged 1 commit into
mainfrom
agent/lifecycle-app-prep

Conversation

@abrichr

@abrichr abrichr commented Sep 2, 2026

Copy link
Copy Markdown
Member

The lifecycle App workflows already refuse anyone but openadapt-lifecycle[bot]. They also read vars.OPENADAPT_LIFECYCLE_* and secrets.OPENADAPT_LIFECYCLE_APP_PRIVATE_KEY. This change doesn't arm those workflows, and it doesn't publish a 7-day signer registry.

GitHub settings already applied on OpenAdaptAI/.github (not in this diff):

  • Environments: production-lifecycle-activation, production-release-admission, qualification-authority-state, qualification-revocation-state, production-lifecycle-feed. synthetic-qualification-evidence-decision was already there.
  • Repo and those environment variables: OPENADAPT_LIFECYCLE_APP_ID=4730735, OPENADAPT_LIFECYCLE_INSTALLATION_ID=156835618, OPENADAPT_LIFECYCLE_ACTOR_ID=321544198.
  • public-trust-signing was not created. The software DSSE profile signs from synthetic-qualification-evidence-decision.

This PR adds a local CLI that builds an unsigned candidate from the Keychain qualification key, then signs it. The result stays activation_state=not-installed and clock=unset. No generated_at / expires_at. Don't copy that JSON onto main.

python3 scripts/qualification_software_ed25519.py local-candidate --revision 1 --from-keychain

After the founder has Keychain item openadapt-lifecycle-app-key, set the App private key as an environment secret. Create each environment first. Do not generate a new App key. Do not delete the Keychain item. Confirm every gh secret set exit status:

for E in \
  production-lifecycle-activation \
  production-release-admission \
  qualification-authority-state \
  qualification-revocation-state \
  production-lifecycle-feed
do
  security find-generic-password -a "$USER" -s openadapt-lifecycle-app-key -w \
    | gh secret set OPENADAPT_LIFECYCLE_APP_PRIVATE_KEY \
        -R OpenAdaptAI/.github --env "$E"
done

The same commands are in the scripts/prepare_lifecycle_change.py module docstring.

Reviewer checks:

  • python3 -m unittest discover -s tests -p 'test_*.py' (247 tests).
  • local-candidate output has activation_state=not-installed, clock=unset, and no generated_at/expires_at.
  • Inactive issuer workflows still contain no secrets., no environment:, and no aws kms.

This does not admit Flow. The issuer stays inactive. The next founder action is the lifecycle App pem in Keychain, then the loop above.

Opened by an agent session, not the founder.

Add a local-candidate CLI that builds an unpublished, Keychain-signed
registry candidate with activation_state=not-installed and no
generated_at/expires_at. Document the gh secret set loop for the
lifecycle App private key once the founder has the Keychain item.
@abrichr
abrichr merged commit 21c6d6e into main Sep 2, 2026
3 checks passed
@abrichr
abrichr deleted the agent/lifecycle-app-prep branch September 2, 2026 17:04
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