class WarpEngine::CI::Woodpecker::SignatureVerifier
Verifies the HTTP signature Woodpecker puts on its configuration extension requests, in either RFC 9421 (Signature-Input) or the older Cavage draft form, against the configured public key (ed25519 PEM). Fetched public keys are cached per URL for the life of the process.
Constants
- CAVAGE_PARAM
-
The pattern of one
key="value"parameter of a CavageSignatureheader.
Public Class Methods
Source
# File lib/warp_engine/ci/woodpecker/signature_verifier.rb, line 22 def fetch_public_key(url) @key_mutex.synchronize do @key_cache[url] ||= Net::HTTP.get(URI.parse(url)) end end
Returns the PEM body at url, fetched once per URL and then cached (thread-safe).
# File lib/warp_engine/ci/woodpecker/signature_verifier.rb, line 37 def initialize(request, public_key: nil, public_key_url: nil) @request = request @public_key = public_key @public_key_url = public_key_url end
- request
-
the incoming ActionDispatch::Request
- public_key
-
the PEM public key, preferred when given
- public_key_url
-
the URL to fetch the PEM public key from otherwise
Source
# File lib/warp_engine/ci/woodpecker/signature_verifier.rb, line 29 def reset_key_cache! @key_mutex.synchronize { @key_cache = {} } end
Empties the public key cache.
Public Instance Methods
Source
# File lib/warp_engine/ci/woodpecker/signature_verifier.rb, line 47 def valid? pem = public_key_pem if pem.blank? Rails.logger.error("[CI::Woodpecker] no public key configured โ rejecting request") return false end key = OpenSSL::PKey.read(pem) if @request.headers["Signature-Input"].present? rfc9421_valid?(key) else cavage_valid?(key) end rescue OpenSSL::PKey::PKeyError, ArgumentError => e Rails.logger.error("[CI::Woodpecker] #{e.class}: #{e.message}") false end
Returns true when the requestโs signature verifies against the public key. Returns false, logging the reason, when no key is configured or can be fetched, the key cannot be read, a signed component is missing, or the content digest or signature does not match.