Skip to content

Enhance HMAC auth plugin to support structured signature headers (Tailscale-style) #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 17, 2025

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jun 17, 2025

The HMAC auth plugin now supports providers like Tailscale that use structured signature headers with comma-separated key-value pairs, while maintaining full backward compatibility with existing webhook providers.

Problem

The existing HMAC plugin supported various webhook providers (GitHub, GitLab, Shopify, Slack) but couldn't handle providers like Tailscale that use:

  • Single header with comma-separated key-value pairs: t=1663781880,v1=0123456789abcdef
  • Timestamp extracted from the signature header itself (not a separate header)
  • Dot-separated payload format: {timestamp}.{body}

Solution

Added minimal, backward-compatible enhancements to support structured headers:

New Configuration Options

  • header_format: "structured" - Enables parsing of comma-separated key-value pairs
  • signature_key: "v1" - Configurable key name for signature in structured header
  • timestamp_key: "t" - Configurable key name for timestamp in structured header
  • Enhanced payload_template to support dot-separated format

Example: Tailscale Configuration

auth:
  type: hmac
  secret_env_key: TAILSCALE_WEBHOOK_SECRET
  header: Tailscale-Webhook-Signature
  algorithm: sha256
  format: "signature_only"
  header_format: "structured"
  signature_key: "v1"
  timestamp_key: "t"
  payload_template: "{timestamp}.{body}"
  timestamp_tolerance: 300

How It Works

  1. Parse structured header: t=1663781880,v1=abc123... → Extract timestamp and signature
  2. Construct signing payload: {timestamp}.{body}1663781880.{"event":"test"}
  3. Validate signature: Standard HMAC validation with secure comparison

Testing & Quality

  • 14 new comprehensive tests for structured header functionality
  • 100% code coverage maintained (892/892 lines)
  • 557 total tests passing, including existing backward compatibility tests
  • Integration tests passing
  • Linting clean with no violations

Security

  • Secure parsing with proper input validation
  • Prevents malformed header injection attacks
  • Maintains all existing security features (timing attack protection, timestamp validation)
  • No changes to existing security-critical code paths

Backward Compatibility

All existing webhook configurations continue to work unchanged:

  • GitHub: X-Hub-Signature-256: sha256=abc123...
  • GitLab: X-Gitlab-Token: sha256=abc123...
  • Shopify: X-Shopify-Hmac-Sha256: abc123...
  • Slack: X-Slack-Signature: v0=abc123...

Documentation

  • Updated inline code documentation with examples
  • Added comprehensive guide in docs/auth_plugins.md
  • Included real-world curl examples for Tailscale-style webhooks

This enhancement makes the hooks framework significantly more versatile for webhook processing across different provider ecosystems without breaking any existing functionality.

Fixes #51.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

@Copilot Copilot AI changed the title [WIP] task: make the hmac auth plugin even more flexible Enhance HMAC auth plugin to support structured signature headers (Tailscale-style) Jun 17, 2025
@Copilot Copilot AI requested a review from GrantBirki June 17, 2025 02:09
Copilot finished work on behalf of GrantBirki June 17, 2025 02:09
@GrantBirki GrantBirki marked this pull request as ready for review June 17, 2025 04:10
@Copilot Copilot AI review requested due to automatic review settings June 17, 2025 04:10
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for structured signature headers (Tailscale-style) to the HMAC auth plugin, while preserving full backward compatibility.

  • Introduces parse_structured_header and integrates structured header handling into the HMAC validation flow.
  • Extends default config and build_config to include header_format, signature_key, and timestamp_key.
  • Adds unit tests for parsing and validating structured headers.
  • Updates documentation with new configuration options and Tailscale examples.

Reviewed Changes

Copilot reviewed 10 out of 4 changed files in this pull request and generated 2 comments.

File Description
spec/unit/lib/hooks/plugins/auth/hmac_spec.rb Added tests for parse_structured_header and structured-header validation
lib/hooks/plugins/auth/hmac.rb Implemented structured-header parsing and integrated in valid?
docs/auth_plugins.md Documented header_format, signature_key, timestamp_key and Tailscale example
.bundle/config Bundler path settings updated (CI-specific, should be reverted)
Comments suppressed due to low confidence (2)

lib/hooks/plugins/auth/hmac.rb:38

  • [nitpick] The inline example uses type: HMAC (uppercase) but elsewhere the plugin type is specified in lowercase (hmac). For consistency, update this example to type: hmac.
#     type: HMAC

.bundle/config:3

  • This file includes CI-specific Bundler paths that should not be committed. Revert or remove these changes to avoid breaking local development environments.
BUNDLE_PATH: "/home/runner/work/hooks/hooks/vendor/bundle"

- Introduced MAX_HEADER_VALUE_LENGTH and MAX_PAYLOAD_SIZE constants for validation.
- Implemented header and payload size validation methods in Base class.
- Updated HMAC and SharedSecret validators to utilize new validation methods.
- Added tests for oversized headers and payloads to ensure compliance with limits.
@GrantBirki GrantBirki merged commit 2de7558 into main Jun 17, 2025
22 checks passed
@GrantBirki GrantBirki deleted the copilot/fix-51 branch June 17, 2025 05:26
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.

task: make the hmac auth plugin even more flexible
2 participants