feat(ans): add ANS agent lifecycle commands#46
Draft
Swaagie wants to merge 1 commit into
Draft
Conversation
Adds `godaddy ans` command group with 14 subcommands covering the full ANS agent lifecycle: register, status, verify-acme, verify-dns, submit-server-csr, submit-identity-csr, csr-status, revoke, search, resolve, events, get-server-certs, get-identity-certs, badge. Authentication uses GODADDY_KEY + GODADDY_SECRET env vars (sso-key format), matching the Go and Rust ANS SDK CLIs. Two gaps are left intentionally unresolved and documented in the PR for discussion: OAuth Bearer token integration and in-process CSR generation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🗒️ the intent of this draft PR is scope discussion and gap identification. This was an easy proof of concept having worked on some fixes for the Rust ANS SDK.
Summary
Adds a
godaddy anscommand group with 14 subcommands covering the complete ANS agent lifecycle, following the existing Effect + EnvelopeWriter patterns exactly.registerstatusverify-acmeverify-dnssubmit-server-csrsubmit-identity-csrcsr-statusrevokesearchresolveeventsget-server-certsget-identity-certsbadgetransparency.ans.godaddy.com)New files
src/core/ans.ts— REST API layer (typed response models + Effect-based API functions)src/cli/commands/ans.ts— 14 subcommands, allEffect.gen+EnvelopeWritertests/integration/ans-smoke.test.ts— command tree, missing-creds error, revocation validationGap 1 — Authentication: OAuth vs API key
Current state: ANS commands authenticate via
GODADDY_KEY+GODADDY_SECRETenvironment variables (Authorization: sso-key key:secret), matching the Go and Rust ANS CLIs.What's not done: The existing
godaddy auth loginOAuth flow stores a Bearer token that ANS endpoints also accept — but only if the token carries the right ANS scope. The current default OAuth scopes (apps.app-registry:read/write) don't include ANS.What needs discussion:
ans:read ans:write?)godaddy auth loginrequest it by default, or as an opt-in--scope ans?Until this is resolved, users must set
GODADDY_KEYandGODADDY_SECRETbefore running anygodaddy anscommand.Gap 2 — CSR generation: no in-process CSR builder
Current state:
godaddy ans registerrequires--server-csr-fileand--identity-csr-file(paths to pre-generated PEM files). The Rust and Go CLIs auto-generate RSA-2048 CSRs with the correct SAN URI (ans://v{version}.{host}), EKU, and key usage extensions.Why it's not auto-generated here: Node.js has no built-in ASN.1 CSR builder. Adding SAN URI to a CSR without a library requires manual DER/ASN.1 encoding. The most suitable library is
@peculiar/x509, but adding a new dependency needs explicit approval.What needs discussion:
@peculiar/x509be added as a dependency? (it's actively maintained, MIT licensed, ~40KB)godaddy ans generate-csrsubcommand that delegates to the Go or Rust CLI under the hood?Until resolved, generate CSRs with:
race-ready-ans register(Rust) orans-cli generate-csr(Go), then pass the output files togodaddy ans register.Implementation notes
Content-Length: 0is set automatically on bodylessPOSTrequests (Akamai requires this — without it you get HTTP 411 from the edge layer)badgeusestransparency.ans[.ote-]godaddy.com— a different base URL from the registry. ThemakeAnsRequesthelper accepts aserviceparameter to switchstatusnext_actions are dynamic:verify-acmeis shown whenPENDING_VALIDATION,verify-dnswhenPENDING_CERTS,revokealways unlessREVOKEDrevokevalidates the reason string client-side against the known enum before sending (ANS returns undocumented 422s for invalid reasons per-state)Test plan
pnpm exec tsc --noEmit— passespnpm run build— passespnpm test tests/integration/ans-smoke.test.ts— validates command tree and error envelopesGODADDY_KEY=xxx GODADDY_SECRET=yyy node dist/cli.js ans register --host example.ai --a2a-url https://example.ai/a2a --server-csr-file server.csr --identity-csr-file identity.csr