Skip to content

feat(resource): build a VerifyRequest from an http.Request - #504

Merged
osanderson merged 1 commit into
mainfrom
feat/resource-verify-request-from-http
Oct 2, 2026
Merged

osanderson merged 1 commit into
mainfrom
feat/resource-verify-request-from-http

Conversation

@osanderson

Copy link
Copy Markdown
Collaborator

Summary

This is the first library addition from the DevX review.

func VerifyRequestFromHTTP(r *http.Request, target *url.URL) VerifyRequest

It fills in every field of the VerifyRequest for r:

  • Method;
  • the Authorization header;
  • every DPoP header (DPoPProofsFromHTTP, so Verify can still refuse more than one);
  • the TLS client certificate (PeerCertificateFromHTTP).

Why. Seven call sites built the struct by hand. Leaving a field out still compiles, and then fails only for the clients that need it:

The server's PushAuthorizationRequestFromHTTP and TokenEndpointRequestFromHTTP exist for exactly this reason; resource had the parts but not the whole.

The URL stays the caller's. target is this endpoint's own fixed external URL (what a DPoP proof's htu names), never one built from r.Host, which the client controls. For a route with path parameters, the doc says to copy a fixed origin and set Path from r.URL.Path, as decoupled-checkout does. target is copied, never aliased.

Adopted:

  • all five demos with a resource server;
  • cmd/conformance-as's UserInfo and accounts handlers;
  • GETTING_STARTED's resource-server step, whose prose now explains what the constructor fills in and what it leaves to the caller.

Tests

  • All fields are taken from the request, with both DPoP headers kept in order.
  • The URL is the target, not the request's own host, and it doesn't alias target.
  • No TLS, no target and no proofs give zero values.
  • Other checks:
    • go test -race ./... and golangci-lint pass;
    • the five demo modules and cmd/conformance-as pass their tests and lint;
    • GETTING_STARTED's snippets still compile.

🤖 Generated with Claude Code

resource.VerifyRequestFromHTTP(r, target) fills in every field of the
VerifyRequest for a request to the protected resource at target: the
method, the Authorization header, every DPoP header, and the TLS client
certificate. Filling the struct by hand compiles with a field left out,
and then fails only for the clients that need it. Four of the demos
left out PeerCertificate, which refuses every mTLS-bound token, and
payroll-run left out DPoPProofs. The server's own FromHTTP constructors
exist for the same reason.

target stays the caller's: this endpoint's fixed external URL, never
one built from the request's Host header. It is copied, never modified.

The five demos, cmd/conformance-as and GETTING_STARTED now use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@osanderson
osanderson force-pushed the feat/resource-verify-request-from-http branch from b15b18c to d0dfec4 Compare October 2, 2026 04:15
@codecov

codecov Bot commented Oct 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

sonarqubecloud Bot commented Oct 2, 2026

Copy link
Copy Markdown

@osanderson
osanderson merged commit 3d0574b into main Oct 2, 2026
17 checks passed
@osanderson
osanderson deleted the feat/resource-verify-request-from-http branch October 2, 2026 04:19
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