Skip to content

feat(aws): sign SigV4 requests through the system OpenSSL - #1351

Merged
shaneutt merged 4 commits into
praxis-proxy:mainfrom
szedan-rh:fix_sigv4_fips
Sep 25, 2026
Merged

shaneutt merged 4 commits into
praxis-proxy:mainfrom
szedan-rh:fix_sigv4_fips

Conversation

@szedan-rh

Copy link
Copy Markdown
Contributor

Summary

aws_sigv4_sign now computes its signature through the system OpenSSL
(EVP digest and signing APIs), so it can ship in the FIPS build. The
aws-sigv4 crate hard-wires RustCrypto hmac/sha2 with no backend
seam and keeps its canonical-request types private, so the SigV4
protocol steps move into filters/src/aws/signing.rs and the crate
becomes a dev-dependency used as the test oracle.

  • praxis_ai_apis::hash::HmacSha256 next to the existing OpenSSL Sha256
  • aws-sigv4-filter added to FIPS_FEATURES and Containerfile.fips
  • make test-fips-provider: unit tests with the RHEL FIPS provider active
  • docs updated (docs/fips.md, docs/features.md, FIPS tooling)

No change to filter configuration, headers set, or error handling.

Related issue

Refs #814

Validation

  • 24 aws:: unit tests, including a 14-case differential test that
    compares every emitted header byte-for-byte with aws-sigv4, the AWS
    published IAM key-derivation vector and the S3 example
  • Same tests with the RHEL FIPS provider active in the test process
  • make lint (includes fips-deps: no denied crate with the filter enabled)
  • Integration example test aws_sigv4
  • Default graph shrinks from 426 to 423 crates

make test-fips still fails the 14 pre-existing agentic_loop tests, which
fail on main as well (see #1335).

Breaking changes

None.

aws_sigv4_sign computed its HMAC-SHA256 through the aws-sigv4 crate,
which hard-wires the pure-Rust hmac/sha2 crates and offers no way to
substitute them, so the filter had to be left out of the FIPS build.

Move the SigV4 canonicalization and key derivation in-tree and compute
SHA-256 and HMAC-SHA256 through the OpenSSL EVP seam in
praxis_ai_apis::hash. aws-sigv4 becomes a dev-dependency: a differential
test checks every header the signer emits against it, alongside the AWS
published vectors. Add aws-sigv4-filter to the FIPS feature set and a
test-fips-provider target that runs the unit tests with the RHEL FIPS
provider active.

Filter configuration and behaviour are unchanged.

Refs praxis-proxy#814

Signed-off-by: szedan <szedan@redhat.com>
@szedan-rh
szedan-rh requested review from a team, alexsnaps and aslakknutsen September 24, 2026 14:56

@leseb leseb left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 — Restore Amazon’s copyright attribution. signing.rs ports substantial aws-sigv4 code nearly line-for-line but replaces its Amazon copyright notice. Apache 2.0 §4 requires retaining applicable notices in derivative source. Keep the Amazon notice and identify Praxis’s modifications before merging. Apache License §4

Comment thread Containerfile.fips Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the doc?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, missed that one. Dropped SigV4 from the list in 09a2745.

…comment

Signed-off-by: szedan <szedan@redhat.com>
@szedan-rh

Copy link
Copy Markdown
Contributor Author

Fair point on the attribution. 09a2745 restores the Amazon notice in signing.rs and states what was ported (path normalization, encoding set, excluded headers, canonical request assembly from aws-sigv4 1.5.3 / aws-smithy-http 0.64.0) and what changed (the crypto now goes through the system OpenSSL).

@shaneutt shaneutt added the blocker This is blocking other work significantly label Sep 24, 2026
@shaneutt shaneutt added this to the v0.4.0 milestone Sep 24, 2026
@shaneutt shaneutt linked an issue Sep 24, 2026 that may be closed by this pull request
3 tasks

@alexsnaps alexsnaps left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aws-sigv4 (+ transitive hmac/sha2) 🔥 Good stuff!

/// duplicate and excluded headers, spaces, query ordering, ports,
/// tokens, regions, services and dates).
#[expect(clippy::too_many_lines, reason = "test data: one entry per canonicalization edge")]
fn differential_cases() -> Vec<Oracle<'static>> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to eventually harden this around canonical_query edges maybe, but I think that's not a real problem right now.

Comment thread apis/src/hash.rs Outdated
if written != SHA256_LEN {
// Cannot happen for SHA-256; treat it as the library misbehaving
// rather than returning a truncated tag.
return Err(ErrorStack::get());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is purely hypothetical as of now... wondering how much a static message would read better than an empty stack. But, again, purely hypothetical (

Comment thread docs/developing/fips.md Outdated
Comment thread docs/developing/fips.md Outdated
Comment thread filters/src/aws/signing.rs
Comment thread filters/src/aws/sigv4.rs
Comment thread Makefile Outdated
Comment thread Makefile
Comment thread Makefile Outdated
The test-fips-provider target passed OPENSSL_CONF through cargo's runner,
which OpenSSL ignores when the path is wrong, so the tests could run on the
default provider and still pass. The run now also sets
PRAXIS_TEST_FIPS_PROVIDER, and the apis and filters test processes assert
that OpenSSL reports FIPS-approved default properties and refuses MD5.
The UBI 9 report stage runs the hash and signing tests the same way, so
CI covers the provider-active path.

Also: HmacError with a static message for the impossible tag length,
stale test comments in sigv4.rs, the report description in
docs/developing/fips.md, and test-fips-provider in make help.

Signed-off-by: szedan <szedan@redhat.com>
@shaneutt
shaneutt self-requested a review September 25, 2026 00:16
@shaneutt
shaneutt merged commit 0048946 into praxis-proxy:main Sep 25, 2026
46 checks passed
@szedan-rh

Copy link
Copy Markdown
Contributor Author

Wrapping up the second round, all in 22a8e47:

  • fips.md, relative OPENSSL_CONF path: doc now shows an absolute path and says a wrong path is silently a non-FIPS run.
  • fips.md, report description: a sha2/hmac finding that names aws-sigv4 now reads as "escaped dev-dependencies" instead of "add a line to FIPS_FEATURES".
  • signing.rs size: 513 lines implementation, 511 tests, most of the tests being the differential table against aws-sigv4.
  • sigv4.rs test comments: the S3 vector comment points at the aws-sigv4 crate that the differential test keeps this aligned with; assertion message says x-amz-content-sha256 is always emitted.
  • CI coverage: the UBI 9 report stage now runs the hash:: and aws:: tests on the FIPS provider, so make fips-check and the fips workflow exercise the provider-active path. Only those groups for now, the full FIPS-set run trips the 14 agentic_loop failures from feat(fips): enable certificate-only PostgreSQL Responses store #1335.
  • make help: added test-fips-provider (test-fips was already listed).
  • Provider state assertion: PRAXIS_TEST_FIPS_PROVIDER is set on cargo itself so it reaches the test binaries whatever the runner does; the apis and filters test processes then assert that OpenSSL reports FIPS default properties and refuses MD5. Checked the negative case, both fail without the provider.
  • Empty error stack on the impossible tag length (alexsnaps): replaced with a small HmacError carrying a static message.

Verified with clippy, make lint, make test-fips-provider and make fips-check on UBI 9 (31 tests on the provider, report clean).

leseb added a commit to leseb/praxis-ai that referenced this pull request Sep 25, 2026
Brings in AWS SigV4 signing through the system OpenSSL (praxis-proxy#1351) on top of
the OpenAI Responses filter rename. Resolved docs/features.md,
docs/fips.md, and Makefile by keeping both the renamed filter names and
the AWS/FIPS additions.

Signed-off-by: Sébastien Han <seb@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocker This is blocking other work significantly

Projects

Development

Successfully merging this pull request may close these issues.

aws_sigv4_sign: FIPS-validated SigV4 signing (investigation)

5 participants