Skip to content

feat: add suport for custom triger authentication#1

Open
djanjic wants to merge 1 commit into
masterfrom
custom-trigger-grpc-auth
Open

feat: add suport for custom triger authentication#1
djanjic wants to merge 1 commit into
masterfrom
custom-trigger-grpc-auth

Conversation

@djanjic

@djanjic djanjic commented Jul 3, 2026

Copy link
Copy Markdown

Checklist:

@djanjic djanjic self-assigned this Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This pull request adds optional gRPC authentication support to CustomTrigger. Two new fields, AuthToken (a SecretKeySelector) and AuthHeader (a string defaulting to "authorization"), are introduced in the Go type and propagated through generated OpenAPI, JSON schema, swagger, protobuf, and deepcopy artifacts. The custom-trigger implementation adds a bearerToken type implementing grpc.PerRPCCredentials, wired into dial-option construction to send the token as gRPC metadata, with accompanying unit tests. Documentation and an example manifest are updated to describe and demonstrate the new fields.

Changes

Area Changes
Type definitions Added AuthToken and AuthHeader fields to CustomTrigger struct
Generated artifacts Updated OpenAPI generated code, JSON schema, swagger spec, proto definitions, and deepcopy logic
Trigger implementation Added bearerToken credential type, defaultAuthHeader constant, and dial-option wiring in NewCustomTrigger
Tests Added unit tests for GetRequestMetadata and RequireTransportSecurity
Documentation & examples Updated APIs.md, build-your-own-trigger.md, and custom-trigger.yaml example

Sequence Diagram(s)

sequenceDiagram
  participant NewCustomTrigger
  participant SecretVolume
  participant bearerToken
  participant grpc.Dial

  NewCustomTrigger->>SecretVolume: read AuthToken secret
  SecretVolume-->>NewCustomTrigger: token value
  NewCustomTrigger->>bearerToken: construct with token, AuthHeader
  NewCustomTrigger->>grpc.Dial: WithPerRPCCredentials(bearerToken)
  grpc.Dial->>bearerToken: GetRequestMetadata()
  bearerToken-->>grpc.Dial: {authHeader: "Bearer <token>"}
Loading

Compact metadata:

  • Estimated code review effort: Medium
  • Lines changed: approximately +182/-0 across 12 files

Related issues: None specified
Related PRs: None specified

Suggested labels: enhancement, api-change, documentation

Suggested reviewers: None specified

Poem:

A token hops through gRPC's door,
"Bearer" whispered, nothing more.
Headers set, the secret's kept,
Tests confirm what code adept,
CustomTrigger, secured once more. 🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title follows conventional commits and clearly describes the custom trigger authentication feature.
Description check ✅ Passed The description matches the repository template and includes the required checklist and draft/codegen notes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch custom-trigger-grpc-auth

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/apis/events/v1alpha1/sensor_types.go (1)

669-673: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Nothing enforces Secure when AuthToken is set.

Per the downstream bearerToken.GetRequestMetadata implementation, the token is sent as "Bearer " + token gRPC metadata on every request regardless of whether Secure is true. Docs recommend enabling secure but nothing validates or warns if a user sets AuthToken without Secure: true, risking the token being sent in plaintext over the wire.

Consider adding a webhook/CRD validation rule (or at minimum a runtime warning) requiring Secure: true when AuthToken is set.

examples/sensors/custom-trigger.yaml (1)

16-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Example doesn't demonstrate the recommended secure: true pairing.

The comment says to "Enable secure to protect the token in transit," but the example doesn't set secure: true alongside authToken. Since this file is a reference example, showing the secure configuration would reinforce the documented best practice.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7c5e204-693f-4065-8623-861c017f6e64

📥 Commits

Reviewing files that changed from the base of the PR and between bdd727e and 5cffa78.

⛔ Files ignored due to path filters (1)
  • pkg/apis/events/v1alpha1/generated.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (11)
  • api/jsonschema/schema.json
  • api/openapi-spec/swagger.json
  • docs/APIs.md
  • docs/sensors/triggers/build-your-own-trigger.md
  • examples/sensors/custom-trigger.yaml
  • pkg/apis/events/openapi/openapi_generated.go
  • pkg/apis/events/v1alpha1/generated.proto
  • pkg/apis/events/v1alpha1/sensor_types.go
  • pkg/apis/events/v1alpha1/zz_generated.deepcopy.go
  • pkg/sensors/triggers/custom-trigger/custom-trigger.go
  • pkg/sensors/triggers/custom-trigger/custom-trigger_test.go

Comment on lines +119 to +127
if ct.AuthToken != nil {
token, err := sharedutil.GetSecretFromVolume(ct.AuthToken)
if err != nil {
return nil, fmt.Errorf("failed to retrieve the auth token, %w", err)
}
if !ct.Secure {
logger.Warn("sending the auth token over an insecure connection, consider enabling 'secure' to protect the credentials in transit")
}
opt = append(opt, grpc.WithPerRPCCredentials(bearerToken{header: ct.AuthHeader, token: token, requireTransportSecurity: ct.Secure}))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

grpc-go PerRPCCredentials RequireTransportSecurity insecure transport bearer token

💡 Result:

In gRPC-Go, when you use PerRPCCredentials (such as a bearer token), the library enforces transport security by default to prevent the insecure transmission of credentials [1][2]. ### The Mechanism The credentials.PerRPCCredentials interface includes a method RequireTransportSecurity() bool [3][4]. * When this method returns true (which is the default for standard implementations like OAuth2/JWT) [2], the gRPC client checks the transport credentials configured for the connection [5]. * If you are using an insecure transport (e.g., via credentials/insecure), the gRPC client will fail to establish the connection or the RPC, as it detects a mismatch between the security requirements of your per-RPC credentials and the underlying transport security [5]. ### How to Resolve the Conflict You have two primary options depending on your security requirements: 1. Enable Transport Security (Recommended): If you must send bearer tokens, the best practice is to configure the transport with TLS [1]. go import "google.golang.org/grpc/credentials" // Example: Using TLS transport creds := credentials.NewClientTLSFromCert(nil, "") conn, err := grpc.NewClient(serverAddr, grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(myTokenAuth), ) 2. Disable Transport Security (Not Recommended for Production): If you are working in a controlled, trusted environment (e.g., local development or service mesh) and absolutely need to disable transport security while using credentials that require it, you must implement a custom PerRPCCredentials type where RequireTransportSecurity() returns false. go type InsecureTokenAuth struct { Token string } func (t InsecureTokenAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { return map[string]string{"authorization": "Bearer " + t.Token}, nil } func (t InsecureTokenAuth) RequireTransportSecurity() bool { return false // Overriding to false allows use over insecure transport } Warning: Setting RequireTransportSecurity() to false allows your credentials to be sent in plaintext. Ensure your network is secure. ### Summary The grpc: the credentials require transport level security error occurs because PerRPCCredentials is explicitly signaling that it should not be used over an insecure connection [5]. Overriding RequireTransportSecurity() to return false is the mechanism provided to bypass this safety check when necessary [6].

Citations:


🏁 Script executed:

# Find the bearerToken implementation
cd pkg/sensors/triggers/custom-trigger && grep -n "type bearerToken" custom-trigger.go

Repository: pipekit/argo-events

Length of output: 186


🏁 Script executed:

# Look at lines 38-60 where bearerToken is defined (based on scratchpad context)
cd pkg/sensors/triggers/custom-trigger && sed -n '38,80p' custom-trigger.go

Repository: pipekit/argo-events

Length of output: 1433


🏁 Script executed:

# Check if RequireTransportSecurity is implemented
cd pkg/sensors/triggers/custom-trigger && grep -A 5 "RequireTransportSecurity" custom-trigger.go

Repository: pipekit/argo-events

Length of output: 352


Fail fast instead of sending bearer tokens over plaintext.

When AuthToken is configured and ct.Secure is false, this sets RequireTransportSecurity to false and still attaches Bearer <token> metadata. A warning does not prevent credential exposure in transit; reject this configuration instead.

Proposed fix
 	if ct.AuthToken != nil {
+		if !ct.Secure {
+			return nil, fmt.Errorf("invalid config, authToken requires secure connection")
+		}
 		token, err := sharedutil.GetSecretFromVolume(ct.AuthToken)
 		if err != nil {
 			return nil, fmt.Errorf("failed to retrieve the auth token, %w", err)
 		}
-		if !ct.Secure {
-			logger.Warn("sending the auth token over an insecure connection, consider enabling 'secure' to protect the credentials in transit")
-		}
-		opt = append(opt, grpc.WithPerRPCCredentials(bearerToken{header: ct.AuthHeader, token: token, requireTransportSecurity: ct.Secure}))
+		opt = append(opt, grpc.WithPerRPCCredentials(bearerToken{header: ct.AuthHeader, token: token, requireTransportSecurity: true}))
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ct.AuthToken != nil {
token, err := sharedutil.GetSecretFromVolume(ct.AuthToken)
if err != nil {
return nil, fmt.Errorf("failed to retrieve the auth token, %w", err)
}
if !ct.Secure {
logger.Warn("sending the auth token over an insecure connection, consider enabling 'secure' to protect the credentials in transit")
}
opt = append(opt, grpc.WithPerRPCCredentials(bearerToken{header: ct.AuthHeader, token: token, requireTransportSecurity: ct.Secure}))
if ct.AuthToken != nil {
if !ct.Secure {
return nil, fmt.Errorf("invalid config, authToken requires secure connection")
}
token, err := sharedutil.GetSecretFromVolume(ct.AuthToken)
if err != nil {
return nil, fmt.Errorf("failed to retrieve the auth token, %w", err)
}
opt = append(opt, grpc.WithPerRPCCredentials(bearerToken{header: ct.AuthHeader, token: token, requireTransportSecurity: true}))
}

@JPZ13 JPZ13 self-requested a review July 6, 2026 08:11
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