Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
djzager
force-pushed
the
fix/goose-system-crypto
branch
from
September 28, 2026 23:12
bceb3a1 to
03130b1
Compare
djzager
marked this pull request as ready for review
September 28, 2026 23:13
dymurray
approved these changes
Sep 29, 2026
The release FIPS scan (openshift/check-payload) rejects a Rust binary that compiles crypto into itself. It detects that from defined ELF symbols: ring_core_/GFp_ (ring), aws_lc_/AWSLC_ (aws-lc-rs), BORINGSSL_ (boring) and OPENSSL_ (statically vendored OpenSSL). A binary with none of those that links libcrypto dynamically passes. Stock Goose fails on both counts: the default rustls-tls feature pulls in aws-lc-rs, and rcgen links ring to generate the self-signed ACP transport certificate. Build goose-cli with --no-default-features --features native-tls,aws-providers,disable-update so the TLS stack is OpenSSL rather than rustls, drop rcgen from the native-tls feature and build the self-signed certificate with OpenSSL instead, and set OPENSSL_NO_VENDOR=1 so openssl-sys cannot fall back to compiling its own OpenSSL. verify-dependencies.sh asserts the resolved graph keeps those crates out, and the ldd check asserts the finished binary really does link the system library. Both run inside the build because together they are the scan's pass condition. The patch touches only the [features] table and acp/transport/tls.rs, so dependency resolution is unchanged and Cargo.lock needs no edit: the build stays --locked and needs no network beyond the normal crate fetch. This moves TLS and certificate generation onto system OpenSSL and leaves the binary carrying no crypto of its own. It is not an audit of every call site -- Goose still compiles sha2 and hmac for OAuth PKCE and pairing codes. Those define no scanned symbol, and check-payload only reaches its crate-name denylist through a cargo-auditable SBOM that this binary does not embed. Also declare openssl-fips-provider in the runtime install. UBI9 and UBI10 both already ship it, but naming it keeps a future base-image change from silently dropping the FIPS module. Finally, replace the CI cache key's ARG GOOSE_VERSION lookup with cache-key.sh. That ARG went away when goose moved to a submodule, so the step reading it fails today; the script keys on the submodule revision, the Containerfile goose build region and the patch files instead. The e2e job that compiles goose checked out without submodules, so images/agent-base/goose-src was empty and the new git apply step failed with "crates/goose/Cargo.toml: No such file or directory". Set submodules: true on that checkout, and have the goose-image action check the submodule is populated before it starts a build, so the next workflow to miss this gets told what is wrong instead of a confusing error from inside the container. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: David Zager <david.j.zager@gmail.com>
djzager
force-pushed
the
fix/goose-system-crypto
branch
from
September 29, 2026 01:55
03130b1 to
34f3d8e
Compare
6 tasks
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.
Why
The MTA 8.3 release workflow runs an
openshift/check-payloadFIPS scan that doesn't run against stage builds. It rejects a Rust binary that compiles crypto into itself, detecting that from defined ELF symbols:ring_core_/GFp_aws_lc_/AWSLC_BORINGSSL_OPENSSL_A binary with none of those that lists
libcryptoinDT_NEEDEDpasses. (Only defined symbols count — a dynamically linked system libcrypto leavesOPENSSL_*undefined, which the scan skips.)Stock Goose fails on both counts: the default
rustls-tlsfeature pulls in aws-lc-rs, andrcgenlinks ring to generate the self-signed ACP transport certificate.What changed
Three things, and they are all load-bearing:
goose-cliwith--no-default-features --features native-tls,aws-providers,disable-update— the TLS stack becomes OpenSSL instead of rustls.rcgenfrom thenative-tlsfeature and build the self-signed certificate with OpenSSL instead. Without this, enablingnative-tlsstill drags ring in throughrcgen, whose only crypto backends are ring and aws-lc-rs.OPENSSL_NO_VENDOR=1soopenssl-syscan't fall back toopenssl-src, which would compile OpenSSL in and define theOPENSSL_*symbols the scan rejects.Two assertions run inside the build, because together they are the scan's pass condition:
verify-dependencies.shfails if the resolved graph containsrustls,ring,aws-lc-rs,aws-lc-sys,aws-lc-fips-sysoropenssl-src, or if it stops containingopenssl/openssl-sys.ldd target/release/goose | grep -q 'libcrypto.so.3'fails if the finished binary doesn't actually link the system library.Also:
openssl-fips-providerdeclared in the runtimednf install. UBI9 and UBI10 both already ship it along with/usr/lib64/ossl-modules/fips.so— verified directly against both images — so this changes nothing today. It's named so a future base-image swap can't silently drop the FIPS module, matching what 🌱 Build Go binaries FIPS-compliant #20 did for ubi-minimal.ARG GOOSE_VERSION, which went away when goose moved to a submodule, so that step fails onmaintoday.cache-key.shkeys on the submodule revision, the Containerfile goose build region, and the patch files instead — and deliberately excludesREADME.mdand itself, so a typo fix doesn't discard a 35-minute compile.images/agent-base/goose-srcwas empty andgit applyfailed withcrates/goose/Cargo.toml: No such file or directory. Setsubmodules: truethere, and thegoose-imageaction now checks the submodule is populated before starting a build, so the next workflow to miss this gets told what's wrong instead of a confusing error from inside the container.Makefileguard.$(shell)swallows a non-zero exit, which tagged the imagegoose-dist:and silently reused the wrong binary. The$(error)sits in the recursively expandedGOOSE_DIST_IMG, so it fires only when a goose build needs the tag —make helpstill works.Patch size
The Goose patch went from 1167 lines across 13 files to 158 lines across 2 files (
crates/goose/Cargo.toml[features]andcrates/goose/src/acp/transport/tls.rs).The entire ~900-line
Cargo.lockdiff is gone: the only manifest change is to a[features]table, which doesn't change dependency resolution, socargo build --lockedstill holds against the unmodified lockfile. Dropped along with it: theoauth2andaws-sigv4crate patches,crypto.rs, thejsonwebtoken-opensslswap, and the PKCE/nanoid/rand conversions across nine files. None of those were reachable by the scan — check-payload only consults its crate-name denylist (sha2,hmac,rsa, …) through acargo auditableSBOM, which this binary doesn't embed.apply.shis gone too. With no crates to stage there's nocurl, no checksum pinning and no network in the patch step — the Containerfile just runsgit apply.Verification
cargo tree --locked --target x86_64-unknown-linux-gnu -p goose-cli --no-default-features --features native-tls,aws-providers,disable-update: 619 crates, zero denied crypto crates,openssl+openssl-syspresent, and--lockedholds.verify-dependencies.shwithUnexpected crypto dependency: ring. The guardrail is real, not decorative.cargo check --locked -p goose --no-default-features --features native-tls --all-targetspasses.native_crypto_certificate_matches_key_and_localhostpasses: the OpenSSL path produces a P-256 / ECDSA-SHA256 self-signed cert that verifies against its own key, withlocalhostand127.0.0.1SANs — the same certificate rcgen was producing.README.mdleaves it unchanged, editing the patch changes it.Scope
This makes the binary carry no crypto of its own and routes TLS and certificate generation through system OpenSSL. It is not an audit of every cryptographic call site. Goose still compiles pure-Rust
sha2/hmacfor OAuth PKCE, pairing codes and similar. Those define no symbol the scan looks for, and the crate-name denylist that would catch them is only reachable via an embedded SBOM this binary doesn't have. If Goose gains one, or the scan grows a source-level check, those call sites are the next thing to move.The reasoning above is written up in
images/agent-base/patches/README.mdso the next person to bump the submodule knows which parts are load-bearing.