Skip to content

add agent and primitives#2

Merged
motdotla merged 3 commits intomainfrom
primitives
Feb 26, 2026
Merged

add agent and primitives#2
motdotla merged 3 commits intomainfrom
primitives

Conversation

@motdotla
Copy link
Contributor

No description provided.

Copy link

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

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

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_command escapes args and then concatenates into a single string, which is then passed to Open3.capture3(command). This reintroduces shell parsing and is less safe/robust than passing arguments as an array to Open3.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
    Agent and Primitives both duplicate the same private vestauth_binary helper.

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.headers and Vestauth::Primitives.verify convenience APIs that delegate to the underlying binary.
  • Exposed Vestauth.primitives alongside existing Vestauth.tool, Vestauth.provider (alias), Vestauth.agent, and Vestauth.binary accessors.
  • Extended Vestauth::Binary with new subcommands:
    • agent_headers(http_method:, uri:, private_key:, id:) → runs vestauth agent headers ...
    • primitives_verify(http_method:, uri:, signature_header:, signature_input_header:, public_key:) → runs vestauth primitives verify ...
  • Added a new file lib/vestauth/primitives.rb implementing the Primitives module.
  • Expanded specs to cover new module exposure and delegation behavior for agent/primitives.

Files touched

  • lib/vestauth.rb (new require_relative and new accessor primitives)
  • lib/vestauth/agent.rb (added headers delegator)
  • lib/vestauth/binary.rb (added 2 new command wrappers)
  • lib/vestauth/primitives.rb (new)
  • spec/vestauth_spec.rb (new expectations + new delegation tests)

Comment on lines 47 to 65
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

Choose a reason for hiding this comment

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

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_key is a String, pass it through as-is (assume it is JSON).
  • If it’s a Hash, do public_jwk = JSON.generate(public_key).
  • Otherwise, raise a clear Vestauth::Error explaining 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"
  end

Reply with "@CharlieHelps yes please" if you’d like me to add a commit with this suggestion.

@charliecreates charliecreates bot removed the request for review from CharlieHelps February 26, 2026 05:33
@motdotla motdotla merged commit f3bc19e into main Feb 26, 2026
2 checks passed
@motdotla motdotla deleted the primitives branch February 26, 2026 05:37
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