Conversation
There was a problem hiding this comment.
The main issues are around input serialization/compatibility and command execution safety. public_key.as_json.to_json introduces an implicit ActiveSupport dependency and will break in plain Ruby environments unless callers provide the exact expected object type. Additionally, run_json_command builds a shell string instead of using Open3.capture3 with argv, which is less robust and increases risk when handling user-provided values like URLs/headers.
Additional notes (2)
- Security |
lib/vestauth/binary.rb:69-69
run_json_commandescapes args and then concatenates into a single string, which is then passed toOpen3.capture3(command). This reintroduces shell parsing and is less safe/robust than passing arguments as an array toOpen3.capture3, especially as inputs include URLs and headers that may contain characters with special meaning.
Even with Shellwords.escape, building a shell command string is unnecessary and makes behavior more platform/shell dependent.
- Maintainability |
lib/vestauth/agent.rb:5-19
AgentandPrimitivesboth duplicate the same privatevestauth_binaryhelper.
This is minor now, but it scales poorly as more modules are added (every module repeats the constructor + privacy pattern).
Summary of changes
What changed
- Added
Vestauth::Agent.headersandVestauth::Primitives.verifyconvenience APIs that delegate to the underlying binary. - Exposed
Vestauth.primitivesalongside existingVestauth.tool,Vestauth.provider(alias),Vestauth.agent, andVestauth.binaryaccessors. - Extended
Vestauth::Binarywith new subcommands:agent_headers(http_method:, uri:, private_key:, id:)→ runsvestauth agent headers ...primitives_verify(http_method:, uri:, signature_header:, signature_input_header:, public_key:)→ runsvestauth primitives verify ...
- Added a new file
lib/vestauth/primitives.rbimplementing thePrimitivesmodule. - Expanded specs to cover new module exposure and delegation behavior for agent/primitives.
Files touched
lib/vestauth.rb(newrequire_relativeand new accessorprimitives)lib/vestauth/agent.rb(addedheadersdelegator)lib/vestauth/binary.rb(added 2 new command wrappers)lib/vestauth/primitives.rb(new)spec/vestauth_spec.rb(new expectations + new delegation tests)
| def primitives_verify(http_method:, uri:, signature_header:, signature_input_header:, public_key:) | ||
| public_jwk = public_key.as_json.to_json | ||
|
|
||
| command = [ | ||
| @executable, | ||
| "primitives", | ||
| "verify", | ||
| http_method, | ||
| uri, | ||
| "--signature", | ||
| signature_header, | ||
| "--signature-input", | ||
| signature_input_header, | ||
| "--public-jwk", | ||
| public_jwk | ||
| ] | ||
|
|
||
| run_json_command(command) | ||
| end |
There was a problem hiding this comment.
primitives_verify serializes public_key via public_key.as_json.to_json, which is a Rails/ActiveSupport-ism and not guaranteed to exist in plain Ruby objects. This makes the gem unexpectedly depend on ActiveSupport conventions and can break for typical key objects (e.g., OpenSSL keys, JWT/JWK objects) unless they implement as_json.
Given this method is part of the public API surface, it should accept either a pre-serialized JWK string/Hash or perform a more robust conversion (e.g., accept a String that is already JSON, or a Hash and call JSON.generate).
Suggestion
Consider making public_key handling explicit and framework-independent by accepting String/Hash inputs and serializing with Ruby’s JSON only.
For example:
- If
public_keyis aString, pass it through as-is (assume it is JSON). - If it’s a
Hash, dopublic_jwk = JSON.generate(public_key). - Otherwise, raise a clear
Vestauth::Errorexplaining what types are accepted.
Sketch:
public_jwk =
case public_key
when String
public_key
when Hash
JSON.generate(public_key)
else
raise Vestauth::Error, "public_key must be a JWK JSON String or a Hash"
endReply with "@CharlieHelps yes please" if you’d like me to add a commit with this suggestion.
No description provided.