Skip to content

feat: add GCP Secret Manager provider#2403

Open
yohamta0 wants to merge 6 commits into
mainfrom
agent/gcp-secret-manager
Open

feat: add GCP Secret Manager provider#2403
yohamta0 wants to merge 6 commits into
mainfrom
agent/gcp-secret-manager

Conversation

@yohamta0

@yohamta0 yohamta0 commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add the gcp-secret-manager DAG secret provider using Application Default Credentials
  • support short IDs and global or regional resource names, versions, regional endpoints, CRC32C verification, and optional JSON field extraction
  • add global GCP project and location configuration, environment bindings, schema coverage, client cleanup, and tests

Testing

  • make fmt
  • go test ./internal/cmn/secrets ./internal/cmn/config ./internal/cmn/schema ./internal/runtime/agent -count=1

Part of #798


Summary by cubic

Adds GCP Secret Manager as a secret provider using Application Default Credentials. Supports short IDs and full resource names (global or regional), versions, regional endpoints, CRC32C checks, and JSON field extraction that preserves values; aligns with Linear #798.

  • New Features

    • New gcp-secret-manager provider with version, project_id, location, and field options; accepts short IDs or full resource names.
    • Uses regional endpoints when location is set and verifies payload CRC32C.
    • Adds global defaults: secrets.gcp.project_id, secrets.gcp.location (env: DAGU_SECRETS_GCP_PROJECT_ID, DAGU_SECRETS_GCP_LOCATION).
    • Normalizes and validates references with clearer errors (trims whitespace, rejects invalid locations, prevents option/resource conflicts).
    • Provider clients are closed on shutdown via registry Close; aggregates Close errors; agent defers it.
  • Bug Fixes

    • Preserve values when extracting a field from JSON secrets (keeps large numbers intact and returns compact JSON for objects).
    • Stabilize notification monitor tests on Windows using OS-aware timeouts.

Written for commit f980d71. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added Google Cloud Secret Manager as a supported secret provider, including configuration for project, location, and version defaults, plus support for full resource-name formats.
    • Added optional JSON field extraction when secrets are stored as JSON objects.
  • Documentation

    • Expanded “TLS and Secrets” documentation with additional secret-management options, including cloud-provider secret stores.
  • Tests

    • Added and updated unit tests covering Google Cloud Secret Manager validation, resolution (including JSON field extraction and checksum verification), and secret-provider cleanup behavior.

Copilot AI review requested due to automatic review settings July 21, 2026 16:24
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds GCP Secret Manager as a secret provider with configuration, reference parsing, regional client caching, checksum validation, JSON field extraction, registry cleanup, dependencies, and tests. Notification monitor tests now use platform-aware timing and shutdown helpers.

Changes

GCP Secret Manager support

Layer / File(s) Summary
GCP secret configuration
go.mod, internal/cmn/config/..., internal/cmn/schema/config.schema.json, README.md
Adds GCP project and location configuration, YAML and environment-variable loading, schema definitions, Google Cloud dependencies, and updated documentation.
GCP Secret Manager resolver
internal/cmn/secrets/field.go, internal/cmn/secrets/gcp_secret_manager.go, internal/cmn/secrets/*_test.go
Registers the provider, validates reference formats, caches clients by location, reads secret versions, verifies CRC32C checksums, and extracts optional JSON fields.
Resolver resource cleanup
internal/cmn/secrets/resolver.go, internal/cmn/secrets/resolver_test.go, internal/runtime/agent/agent.go
Adds registry cleanup with joined errors and closes the registry after secret resolution.

Notification monitor test timing

Layer / File(s) Summary
Platform-aware monitor test synchronization
internal/service/chatbridge/monitor_state_test.go
Adds shared monitor configuration and shutdown helpers, scales eventual timeouts on Windows, and applies them to monitor assertions.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant SecretRegistry
  participant GCPSecretManagerResolver
  participant GCPSecretManager
  Agent->>SecretRegistry: Resolve secret reference
  SecretRegistry->>GCPSecretManagerResolver: Resolve
  GCPSecretManagerResolver->>GCPSecretManager: AccessSecretVersion
  GCPSecretManager-->>GCPSecretManagerResolver: Secret payload and checksum
  GCPSecretManagerResolver-->>SecretRegistry: Extracted secret value
  SecretRegistry-->>Agent: Resolved secret
  Agent->>SecretRegistry: Close
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a GCP Secret Manager provider.
Description check ✅ Passed The description covers the summary, key changes, testing, and related issue, though it does not follow every template section exactly.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/gcp-secret-manager

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new GCP Secret Manager-backed secret provider to Dagu’s secret-resolution system, including global configuration defaults and lifecycle cleanup, aligning with the secure “load-at-runtime” secret management direction in #798.

Changes:

  • Implement gcp-secret-manager secret provider with support for short IDs, fully-qualified resource names (global/regional), version selection, regional endpoints, CRC32C verification, and optional JSON field extraction.
  • Add secrets.gcp.{project_id,location} to config definition/loader/env bindings and extend the config JSON schema accordingly.
  • Ensure secret providers can be cleaned up via Registry.Close() and add tests for the provider and JSON field extraction.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Updates documentation blurb to include GCP Secret Manager in secret management options.
internal/runtime/agent/agent.go Closes the secrets registry after resolving secrets to release provider resources.
internal/cmn/secrets/resolver.go Adds Registry.Close() to close any providers that implement Close() error.
internal/cmn/secrets/resolver_test.go Updates built-in provider expectations to include gcp-secret-manager.
internal/cmn/secrets/gcp_secret_manager.go Implements the GCP Secret Manager resolver and client lifecycle management.
internal/cmn/secrets/gcp_secret_manager_test.go Adds tests for parsing, resolution behavior, error cases, and close semantics.
internal/cmn/secrets/field.go Adds JSON field selection helper for secret payloads.
internal/cmn/secrets/field_test.go Tests JSON field selection behavior and error hygiene.
internal/cmn/schema/config.schema.json Extends config schema with secrets.gcp defaults.
internal/cmn/config/loader.go Loads secrets.gcp defaults and adds env bindings.
internal/cmn/config/loader_test.go Verifies YAML/env/config-scope loading for secrets.gcp.
internal/cmn/config/definition.go Adds GCPSecretsDef to the config definition model.
internal/cmn/config/config.go Adds GCPSecretsConfig to runtime config.
go.mod Adds Secret Manager client dependency and related Google API dependency.
go.sum Updates dependency checksums for newly introduced modules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/cmn/secrets/gcp_secret_manager_test.go
Comment thread internal/cmn/secrets/resolver_test.go
Comment thread internal/cmn/secrets/resolver_test.go Outdated
Comment thread internal/cmn/secrets/resolver_test.go

@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 (1)
internal/cmn/secrets/resolver.go (1)

278-295: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider filtering out nil errors before appending.

While errors.Join safely ignores nil values, it is slightly more idiomatic to only append actual errors to the slice.

♻️ Proposed refactor
 	var errs []error
 	for _, resolver := range resolvers {
 		if closer, ok := resolver.(interface{ Close() error }); ok {
-			errs = append(errs, closer.Close())
+			if err := closer.Close(); err != nil {
+				errs = append(errs, err)
+			}
 		}
 	}
 	return errors.Join(errs...)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/cmn/secrets/resolver.go` around lines 278 - 295, Update
Registry.Close to append only non-nil errors returned by each resolver’s Close
method, while preserving the existing resolver iteration and errors.Join
aggregation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/cmn/secrets/gcp_secret_manager_test.go`:
- Around line 131-163: Fix the ChecksumMismatch test case in
TestGCPSecretManagerResolverErrors by replacing the invalid new(int64(1))
expression with a valid *int64 value containing 1, while preserving the existing
CRC32C mismatch setup and assertion.

---

Nitpick comments:
In `@internal/cmn/secrets/resolver.go`:
- Around line 278-295: Update Registry.Close to append only non-nil errors
returned by each resolver’s Close method, while preserving the existing resolver
iteration and errors.Join aggregation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6279a178-4b9a-46d5-8e0a-111db8f5fc9a

📥 Commits

Reviewing files that changed from the base of the PR and between 8718338 and 17bd2f5.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (14)
  • README.md
  • go.mod
  • internal/cmn/config/config.go
  • internal/cmn/config/definition.go
  • internal/cmn/config/loader.go
  • internal/cmn/config/loader_test.go
  • internal/cmn/schema/config.schema.json
  • internal/cmn/secrets/field.go
  • internal/cmn/secrets/field_test.go
  • internal/cmn/secrets/gcp_secret_manager.go
  • internal/cmn/secrets/gcp_secret_manager_test.go
  • internal/cmn/secrets/resolver.go
  • internal/cmn/secrets/resolver_test.go
  • internal/runtime/agent/agent.go

Comment thread internal/cmn/secrets/gcp_secret_manager_test.go
Copilot AI review requested due to automatic review settings July 21, 2026 16:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

internal/cmn/secrets/resolver_test.go:25

  • NewRegistry() now includes the GCP Secret Manager provider, but this test no longer asserts it (or the expected number of built-in providers). This weakens coverage and could allow accidental removal/renaming of the new provider without failing tests.
	assert.Contains(t, providers, "env")
	assert.Contains(t, providers, "file")
	assert.Contains(t, providers, "vault")
	assert.Contains(t, providers, "kubernetes")
}

internal/cmn/secrets/resolver_test.go:323

  • Registry.Providers() test no longer verifies the new built-in GCP Secret Manager provider is present (and no longer checks the expected built-in count). Adding an explicit assertion here would better protect against regressions in provider registration.
	assert.Contains(t, providers, "env")
	assert.Contains(t, providers, "file")
	assert.Contains(t, providers, "vault")
	assert.Contains(t, providers, "kubernetes")

internal/cmn/secrets/resolver_test.go:329

  • After registering the custom provider, the test should also assert the updated provider count to ensure Register actually adds a new provider entry rather than replacing an existing one.
	mock := &mockResolver{mockName: "custom"}
	registry.Register("custom", mock)

	providers = registry.Providers()
	assert.Contains(t, providers, "custom")

@yohamta0

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI review requested due to automatic review settings July 21, 2026 17:05
@yohamta0

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.

Comment thread internal/cmn/secrets/gcp_secret_manager.go Outdated
Comment thread internal/cmn/secrets/gcp_secret_manager.go Outdated
Comment thread internal/cmn/secrets/resolver.go
Copilot AI review requested due to automatic review settings July 21, 2026 17:47
@yohamta0

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 21, 2026 18:21
@yohamta0

Copy link
Copy Markdown
Collaborator Author

Addressed the CodeRabbit nitpick from the review summary. Registry.Close now collects only non-nil close errors before errors.Join. The secrets and runtime-agent race tests pass.

@yohamta0

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

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.

2 participants