Skip to content

[go-fan] Go Module Review: golang.org/x/crypto #35444

@github-actions

Description

@github-actions

Go Fan Report: golang.org/x/crypto

Module Overview

golang.org/x/crypto is the Go team's supplementary cryptography library — primitives that live outside the standard library, covering NaCl, OpenPGP, SSH, OCSP, modern hashes/KDFs (BLAKE2, SHA-3, Argon2, scrypt), and low-level ciphers/curves.

The project is on v0.52.0, the latest published tag, and the upstream repo was pushed yesterday (2026-05-27). Recent activity is almost entirely in the ssh/ sub-package (several CVE-class fixes — userauth attempt caps, source-address bypass, exit-status panic). gh-aw does not import ssh/, so none of those changes affect this codebase.

Current Usage in gh-aw

gh-aw uses golang.org/x/crypto for exactly one purpose: encrypting GitHub Actions secrets against a repository's NaCl public key before uploading them via the REST API.

  • Files: 2 (pkg/cli/secret_set_command.go, pkg/cli/secret_set_command_test.go). pkg/cli/deps_test.go only references the version string in test fixtures.
  • Sub-package imported: golang.org/x/crypto/nacl/box
  • Production APIs used: box.SealAnonymous
  • Test APIs used: box.GenerateKey, box.OpenAnonymous (for round-trip)
  • Call site: setRepoSecretencryptWithPublicKeybox.SealAnonymous, output base64-encoded and PUT to /repos/{owner}/{repo}/actions/secrets/{name}
Why SealAnonymous is the right call here

GitHub's Actions Secrets API requires libsodium-compatible sealed-box encryption — sender has only the repo's 32-byte public key and no keypair of its own. box.SealAnonymous matches that contract exactly; box.Seal would be wrong (requires a sender private key the API does not consume).

Research Findings

The nacl/box sub-package is mature and stable — no churn in years. Project is fully up to date.

Recent upstream commits (none affect nacl/box)
  • ssh: cap total userauth attempts per server connection (2026-05-24)
  • ssh: prevent malformed exit-status panic (2026-05-20)
  • ssh: fix source-address critical option bypass (2026-05-15) — security
  • ssh: add AuthCallback to ClientConfig (2026-03-25)
  • ssh/agent: support parallel signing using request pipelining (2026-04-19)
  • ssh: add openssh controlmaster socket support (2025-12-29)

All of the above are in ssh/ and ssh/agent. gh-aw imports neither.

Improvement Opportunities

Quick Wins

1. Use slice-to-array-pointer conversion instead of copypkg/cli/secret_set_command.go:227-228

The Go directive in go.mod is go 1.26.3, so the Go 1.17+ idiom is available:

// before
var pk [publicKeySize]byte
copy(pk[:], raw)
ciphertext, err := box.SealAnonymous(nil, []byte(plaintext), &pk, rand.Reader)

// after
pk := (*[publicKeySize]byte)(raw)
ciphertext, err := box.SealAnonymous(nil, []byte(plaintext), pk, rand.Reader)

The explicit length check at secret_set_command.go:223 already guarantees the conversion is safe. Drops one line and the 32-byte copy.

2. Use the exported box.AnonymousOverhead constant in testspkg/cli/secret_set_command_test.go:130-134

The test currently hardcodes the 48-byte overhead in a comment and asserts len(encrypted) >= 64. Replace with the exported constant so the assertion tracks any future upstream change:

minCipher := box.AnonymousOverhead                       // 48
minBase64 := base64.StdEncoding.EncodedLen(minCipher)    // 64
if len(encrypted) < minBase64 {
    t.Errorf("encrypted length = %d, expected at least %d", len(encrypted), minBase64)
}

Best Practice Alignment

The current code is already in good shape:

  • Uses crypto/rand.Reader for entropy
  • Length-checks the decoded public key before copying
  • Picks SealAnonymous (the libsodium-compatible primitive GitHub expects), not Seal
  • Has a real-key-pair round-trip test, not a mock
  • The doc comment on encryptWithPublicKey records the algorithm stack (Curve25519 + XSalsa20 + Poly1305), which most projects skip

Feature Opportunities

None pressing. The current import surface is intentionally narrow. Latent options worth noting only if related work surfaces later:

  • golang.org/x/crypto/ssh/agent — only if gh-aw ever needs ssh-agent integration for Git auth
  • golang.org/x/crypto/sha3 — only if SHAKE/cSHAKE hashing is ever needed (current hashing in pkg/parser/frontmatter_hash.go and pkg/workflow/cache_integrity.go uses stdlib crypto/sha256, which is correct)

Recommendations

In priority order:

  1. Apply the slice-to-array-pointer conversion in pkg/cli/secret_set_command.go (quick, idiomatic, ~2-line diff).
  2. Swap the test's magic-number overhead for box.AnonymousOverhead (~3-line diff, self-documenting).
  3. No version bump needed — already on v0.52.0.
  4. No exposure to the recent SSH security fixes — confirmed via grep; not imported anywhere.

Next Steps

  • Open a small PR bundling the two quick wins above (single file each, no behavior change).
  • No follow-up monitoring needed for upstream nacl/box — it is a stable, frozen API.

Generated by Go Fan
Module summary saved to: scratchpad/mods/golang-x-crypto.md
Workflow run: §26565171457

Generated by 🐹 Go Fan · opus47 7.8M ·

  • expires on May 29, 2026, 9:08 AM UTC

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions