Skip to content

feat: GCP Secret Manager integration for external secrets management#16663

Closed
amor71 wants to merge 18 commits into
openclaw:mainfrom
amor71:feat/gcp-secret-manager
Closed

feat: GCP Secret Manager integration for external secrets management#16663
amor71 wants to merge 18 commits into
openclaw:mainfrom
amor71:feat/gcp-secret-manager

Conversation

@amor71

@amor71 amor71 commented Feb 15, 2026

Copy link
Copy Markdown

Closes #13610

Labels: size: XS enhancement security

Summary

Adds native GCP Secret Manager integration so credentials can be stored in an encrypted, access-controlled secrets store instead of plaintext files on disk.

What

  • Secret reference syntax${gcp:secret-name} in config files, resolved at runtime
  • GcpSecretProvider — fetches secrets via @google-cloud/secret-manager (optional, dynamically imported)
  • In-memory cache with configurable TTL and stale-while-revalidate fallback
  • Per-agent isolation — each agent uses its own GCP service account; IAM bindings enforce access at the GCP level
  • CLI commandsopenclaw secrets setup|test|list|set|migrate
  • Migration scripts — bootstrap GCP, migrate plaintext secrets, set per-secret IAM bindings
  • Config schema — new secrets section in openclaw.json (Zod-validated)
  • Async post-processingresolveConfigSecrets() runs after loadConfig(); existing sync call sites unchanged
  • Full documentation — concept page, GCP Console guide, worked multi-agent example

Files

File Purpose
src/config/secret-resolution.ts Core module — ref parsing, GcpSecretProvider, cache, config tree walking
src/config/secret-resolution.test.ts 74 unit tests
src/commands/secrets.ts CLI commands
src/commands/secrets.test.ts 22 CLI tests
docs/concepts/secrets.md Full documentation with worked multi-agent example
docs/concepts/secrets-gcp-console-guide.md Step-by-step GCP Console setup guide
scripts/secrets/bootstrap-gcp.sh Enable APIs, create service accounts, generate keys
scripts/secrets/migrate-secrets.sh Scan, store, verify, purge plaintext credentials
scripts/secrets/set-iam-bindings.sh Set per-secret IAM bindings for agent isolation
src/config/config.ts Re-exports
src/config/types.openclaw.ts TypeScript types
src/config/zod-schema.ts Schema validation
test/setup.ts Default GCP mock for test env
package.json @google-cloud/secret-manager as devDependency

Design decisions

  • Option A (async post-processing): loadConfig() stays synchronous; resolveConfigSecrets() is a separate async step. Least invasive.
  • Optional dependency: @google-cloud/secret-manager is dynamically imported. Clear error if not installed.
  • Backward compatible: No secrets config = no behavior change. Entirely opt-in.
  • Per-agent isolation via IAM: Not application-level filtering — GCP itself blocks unauthorized access.

Testing

  • 96 tests (74 unit + 22 CLI), all passing
  • 0 lint errors (oxlint --type-aware)
  • End-to-end tested on live GCP Secret Manager with real credentials
  • Per-agent isolation verified: agents cannot read each other's secrets (PERMISSION_DENIED)

Requirements & Design docs

🤖 This PR was developed with AI assistance (Claude Opus via OpenClaw), per CONTRIBUTING.md guidelines.

Greptile Summary

This PR adds comprehensive secrets management support for GCP, AWS, Azure, and HashiCorp Vault, along with rotation reminders and auto-rotation for gateway tokens. The implementation includes secret reference syntax (${provider:secret-name}), in-memory caching with TTL, lazy-loaded optional dependencies, CLI commands, migration scripts, and extensive test coverage (96 tests).

Key changes:

  • Core secret resolution with 4 provider implementations (GCP, AWS, Azure, Vault)
  • Auto-rotation system for gateway tokens with configurable intervals
  • Rotation reminder system with snooze capabilities
  • Per-agent isolation via IAM bindings (GCP)
  • CLI commands for setup, testing, listing, setting, and migrating secrets
  • Full backward compatibility (opt-in via secrets config section)

Issues found:

  • Schema mismatch: zod-schema.ts:634-651 only allows gcp provider but code registers both gcp and aws in buildSecretProviders(), causing AWS configs to fail validation
  • Documentation inconsistency: docs/concepts/secrets.md lists AWS/Azure/Vault as "Planned" but they're fully implemented with tests
  • Minor redundancy in AWS provider: setSecret() calls PutSecretValueCommand after CreateSecretCommand when the create already stores the value

Confidence Score: 3/5

  • Safe to merge after fixing schema validation for AWS provider
  • Strong implementation with comprehensive tests (96 passing), proper error handling, and security best practices. However, the schema bug prevents AWS provider configs from validating, which will cause runtime failures for users trying AWS. Documentation mismatches are minor but should be corrected. The auto-rotation and multi-provider features add complexity that warrants careful review of edge cases.
  • src/config/zod-schema.ts needs AWS/Azure/Vault provider schemas added

Last reviewed commit: 6ec4efc

Add a secrets resolution layer that intercepts ${gcp:SECRET_NAME} references
in openclaw.json config values and resolves them from Google Cloud Secret Manager.

Features:
- New ${gcp:secret-name} syntax for referencing secrets in config values
- Lazy loading: secrets are fetched only when referenced
- In-memory caching with configurable TTL (default: 5 minutes)
- Parallel resolution of multiple secret references
- Dynamic import of @google-cloud/secret-manager (optional dependency)
- Clear error messages for missing providers or failed resolution

Config syntax:
  {
    "secrets": {
      "providers": {
        "gcp": { "project": "my-project" }
      }
    },
    "channels": {
      "slack": {
        "botToken": "${gcp:slack-bot-token}"
      }
    }
  }

Closes openclaw#13610 (GCP portion)

🤖 AI-assisted (Claude) — fully tested
@jheeanny

Copy link
Copy Markdown

GCP Secret Manager integration for config secrets is a solid choice. We use secret references in config files (secret://projects/.../secrets/...) and cache secrets in memory with short TTL. How do you handle secret rotation and access error fallback?

Red-phase tests covering:
- Secret reference parsing (valid, invalid, escaped, mixed, env var distinction)
- Config tree walking (nested objects, arrays, primitives, fast path)
- Cache behavior (TTL, expiry, stale-while-revalidate, clear)
- GCP provider (mock client: fetch, not found, permission denied, timeout, version pin, dynamic import)
- Error handling (unknown provider, unconfigured provider, path context, partial failure)
- CLI commands (secrets test/list/setup/migrate/set)
@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: XL and removed size: L labels Feb 15, 2026
Rye added 9 commits February 14, 2026 19:57
…t suite

- Add secret-resolution.ts: core resolution module with GcpSecretProvider
- Add secrets.ts: CLI commands (setup, migrate, test, list, set)
- 96 tests passing (74 unit + 22 CLI)
-  reference syntax, in-memory cache with TTL
- Stale-while-revalidate, parallel resolution, clean error handling
- Dynamic import of @google-cloud/secret-manager (optional dep)
- Remove old secret-substitution files, update config.ts exports

Refs: openclaw#13610
AI-assisted: Yes (Claude Opus via OpenClaw)
@amor71 amor71 changed the title feat: add GCP Secret Manager integration for config secrets resolution feat: GCP Secret Manager integration for external secrets management Feb 15, 2026
- scripts/secrets/bootstrap-gcp.sh — enable APIs, create SAs, generate keys
- scripts/secrets/migrate-secrets.sh — scan, store, verify, purge plaintext
- scripts/secrets/set-iam-bindings.sh — per-secret IAM for agent isolation
- docs/concepts/secrets-gcp-console-guide.md — step-by-step Console walkthrough
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation scripts Repository scripts labels Feb 15, 2026
@amor71
amor71 marked this pull request as ready for review February 15, 2026 03:24

@greptile-apps greptile-apps Bot 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.

15 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment thread src/config/secret-resolution.ts
Comment thread src/config/secret-resolution.ts
Comment thread scripts/secrets/migrate-secrets.sh Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a62240644b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/config.ts
Comment on lines +23 to +24
resolveConfigSecrets,
configNeedsSecretResolution,

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.

P1 Badge Invoke secret resolution in the config load path

This change only re-exports resolveConfigSecrets but does not hook it into any runtime config-loading path; in this commit, non-test code still reads config synchronously and never calls the resolver, so ${gcp:...} values remain unresolved during normal execution. That makes the new secrets feature effectively inert unless every caller manually adds an extra async resolution step.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is intentional per the design doc (Option A): loadConfig() stays synchronous and returns config with unresolved ${gcp:...} refs. A separate async resolveConfigSecrets(config) is called after load. The gateway startup code would await secret resolution before accepting connections.

Wiring into io.ts or the gateway startup is left for the maintainers to decide where it best fits in the existing startup flow — this PR provides the building blocks without touching the critical sync config path.

Comment thread src/config/zod-schema.ts
Comment on lines +92 to +95
constructor(config: { project: string; cacheTtlSeconds?: number; credentialsFile?: string }) {
this.project = config.project;
this.cacheTtlMs = (config.cacheTtlSeconds ?? 300) * 1000;
}

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.

P1 Badge Honor credentialsFile when creating GCP clients

Although credentialsFile is accepted in the GCP provider config type, the constructor drops it and getClient() always instantiates SecretManagerServiceClient with no options. In multi-agent deployments this forces ADC/default credentials for all secret reads, so configured per-agent keyfiles are ignored and IAM isolation-by-keyfile cannot work as intended.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

You're right — credentialsFile was accepted but never passed to the client constructor. Fixed: getClient() now passes { keyFilename: this.credentialsFile } when configured. This is essential for per-agent isolation where each agent authenticates with its own service account key.

@amor71

amor71 commented Feb 15, 2026

Copy link
Copy Markdown
Author

@jheeanny Great questions!

Secret rotation: Secrets are cached in memory with a configurable TTL (default 5 minutes). When you update a secret in GCP Secret Manager, agents pick up the new value after the cache expires — no restart needed. You can also force a cache clear via SIGUSR1 restart or clearSecretCache().

Access error fallback: We use stale-while-revalidate — if the provider is unreachable and there's an expired cache entry, we serve the stale value and log a warning. For hard failures (secret not found, permission denied), we throw a SecretResolutionError with clear context (which secret, which provider, which config path). The system doesn't crash — only the feature depending on that secret fails.

Network timeouts get one automatic retry before falling back to cache or throwing.

…etClient()

- Added credentialsFile to Zod schema and TypeScript types
- GcpSecretProvider now passes keyFilename to SecretManagerServiceClient
- Essential for per-agent isolation (each agent uses its own SA key)
@akoscz

akoscz commented Feb 15, 2026

Copy link
Copy Markdown
Contributor

Nice work on this! We have a similar PR open (#11539) that takes a multi-provider approach (GCP, env, OS keyring, + stubs for AWS/Vault/1Password/etc), but honestly your GCP implementation is more polished — the CLI tooling, per-agent isolation via IAM bindings, migration scripts, and stale-while-revalidate caching are all things we didn't get to.

We'd love to build the multi-provider abstraction on top of your implementation rather than compete with it. If this lands, we could contribute a follow-up PR that extracts a SecretsProvider interface from your GcpSecretProvider and adds env/keyring/etc providers behind it — keeping your GCP work as the reference implementation.

Would you be open to that kind of collaboration?

@amor71

amor71 commented Feb 15, 2026

Copy link
Copy Markdown
Author

@akoscz Really appreciate this — and yeah, collaboration makes way more sense than competing PRs.

Looking at your PR (#11539), the SecretsProvider interface is solid and your env/keyring implementations are exactly the kind of thing we shouldn't duplicate. Here's what I'm thinking:

Merge strategy:

  1. Land our GCP PR first (since your review confirms the implementation is more complete for that provider)
  2. You extract the SecretsProvider interface as a follow-up, using our GcpSecretProvider as the reference implementation
  3. Port your env + keyring providers behind that interface

What we'll contribute next:
We're going to implement the three big cloud/enterprise providers that are currently stubbed or missing:

  • AWS Secrets Manager — largest cloud user base, critical gap
  • Azure Key Vault — third major cloud, currently not even stubbed
  • HashiCorp Vault — the standard for self-hosted and hybrid enterprise setups

We'll follow the same patterns as our GCP implementation (CLI tooling, caching with TTL, stale-while-revalidate, per-agent isolation where the platform supports it, comprehensive tests).

Division of labor proposal:

  • Us: GCP (done) → AWS, Azure, Vault
  • You: SecretsProvider interface extraction → env, keyring, and whatever else you want to pick up (1Password, Doppler, Bitwarden)

Happy to coordinate on the interface contract before we both start building. Want to open a tracking issue or discussion thread for this?

@amor71

amor71 commented Feb 15, 2026

Copy link
Copy Markdown
Author

@jheeanny Following up on your rotation question — we've added a full manual key rotation reminder system to our requirements. Many secrets (Alpaca, Anthropic, OpenAI, etc.) can't be rotated programmatically, so we designed a system to handle those:

  • Per-secret rotation policy — each secret can be classified as auto, manual, or dynamic with a configurable rotation interval
  • Proactive reminderssecret:review-due events when rotation interval elapses, secret:expiring-soon for keys with hard TTLs
  • Failure detectionsecret:auth-failed events on 401/403 so admins know immediately when a key dies
  • CLI visibilityopenclaw secrets remind list shows rotation status, overdue keys, and next review dates
  • Snooze & ack — snooze reminders or acknowledge rotation via CLI

For keys that can be auto-rotated, we're also adding provider-native rotation support (AWS Lambda, Azure Event Grid, GCP Pub/Sub, Vault dynamic secrets/leases) — see our updated design docs.

Full requirements: https://github.com/amor71/openclaw-secrets/blob/main/REQUIREMENTS-gcp-secrets.md (§7)
Multi-provider expansion: https://github.com/amor71/openclaw-secrets-providers/blob/main/REQUIREMENTS.md (§11)

@amor71

amor71 commented Feb 16, 2026

Copy link
Copy Markdown
Author

Update: Security PR Status

This PR (GCP Secret Manager + AWS + Azure + Vault integration) is still open and ready for review. 130+ tests, auto-rotation, NIST-based intervals.

Related Work

The Agents Plane project (issue #17299) now uses Secret Manager extensively for agent API key management:

  • Per-agent secrets (agent-{name}-api-key, agent-{name}-config)
  • ExecStartPre fetches keys from SM on every gateway boot — never persists on disk
  • Agent can write its own key to SM when user provides one (via store_key.py)

This validates the Secret Manager integration in a real multi-tenant deployment. Happy to address any review comments.

Fork: https://github.com/amor71/openclaw (branch: feat/gcp-secret-manager)
Docs: https://github.com/amor71/openclaw-secrets
Providers: https://github.com/amor71/openclaw-secrets-providers

@steipete

Copy link
Copy Markdown
Contributor

It'll take me a while to look into this - right now focus is mostly on fixes and security.

@steipete steipete closed this Feb 16, 2026
@steipete steipete reopened this Feb 17, 2026

@greptile-apps greptile-apps Bot 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.

27 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment thread src/config/zod-schema.ts
Comment on lines +634 to +651
secrets: z
.object({
providers: z
.object({
gcp: z
.object({
project: z.string(),
cacheTtlSeconds: z.number().int().nonnegative().optional(),
credentialsFile: z.string().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),

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.

Schema only allows gcp provider but buildSecretProviders() in secret-resolution.ts:287-320 registers both gcp and aws providers. AWS config won't validate.

Suggested change
secrets: z
.object({
providers: z
.object({
gcp: z
.object({
project: z.string(),
cacheTtlSeconds: z.number().int().nonnegative().optional(),
credentialsFile: z.string().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
secrets: z
.object({
providers: z
.object({
gcp: z
.object({
project: z.string(),
cacheTtlSeconds: z.number().int().nonnegative().optional(),
credentialsFile: z.string().optional(),
})
.strict()
.optional(),
aws: z
.object({
region: z.string(),
cacheTtlSeconds: z.number().int().nonnegative().optional(),
profile: z.string().optional(),
credentialsFile: z.string().optional(),
roleArn: z.string().optional(),
externalId: z.string().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/config/zod-schema.ts
Line: 634:651

Comment:
Schema only allows `gcp` provider but `buildSecretProviders()` in `secret-resolution.ts:287-320` registers both `gcp` and `aws` providers. AWS config won't validate.

```suggestion
    secrets: z
      .object({
        providers: z
          .object({
            gcp: z
              .object({
                project: z.string(),
                cacheTtlSeconds: z.number().int().nonnegative().optional(),
                credentialsFile: z.string().optional(),
              })
              .strict()
              .optional(),
            aws: z
              .object({
                region: z.string(),
                cacheTtlSeconds: z.number().int().nonnegative().optional(),
                profile: z.string().optional(),
                credentialsFile: z.string().optional(),
                roleArn: z.string().optional(),
                externalId: z.string().optional(),
              })
              .strict()
              .optional(),
          })
          .strict()
          .optional(),
      })
      .strict()
      .optional(),
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +194 to +200
// CreateSecret already stores the value, but if we want to be explicit:
await client.send(
new sdk.PutSecretValueCommand({
SecretId: secretName,
SecretString: value,
}),
);

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.

Calling PutSecretValueCommand after CreateSecretCommand is redundant since CreateSecretCommand already stores the initial value.

Suggested change
// CreateSecret already stores the value, but if we want to be explicit:
await client.send(
new sdk.PutSecretValueCommand({
SecretId: secretName,
SecretString: value,
}),
);
await client.send(
new sdk.CreateSecretCommand({
Name: secretName,
SecretString: value,
}),
);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/config/aws-secret-provider.ts
Line: 194:200

Comment:
Calling `PutSecretValueCommand` after `CreateSecretCommand` is redundant since `CreateSecretCommand` already stores the initial value.

```suggestion
        await client.send(
          new sdk.CreateSecretCommand({
            Name: secretName,
            SecretString: value,
          }),
        );
```

How can I resolve this? If you propose a fix, please make it concise.

Comment thread docs/concepts/secrets.md
Comment on lines +24 to +31

| Provider | Status |
| ------------------- | ------------ |
| GCP Secret Manager | ✅ Supported |
| AWS Secrets Manager | Planned |
| HashiCorp Vault | Planned |
| Azure Key Vault | Planned |

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.

Documentation says AWS/Vault/Azure are "Planned" but they're fully implemented in src/config/aws-secret-provider.ts, src/config/azure-secret-provider.ts, src/config/vault-secret-provider.ts. Update status to "✅ Supported".

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/concepts/secrets.md
Line: 24:31

Comment:
Documentation says AWS/Vault/Azure are "Planned" but they're fully implemented in `src/config/aws-secret-provider.ts`, `src/config/azure-secret-provider.ts`, `src/config/vault-secret-provider.ts`. Update status to "✅ Supported".

How can I resolve this? If you propose a fix, please make it concise.

paperMoose added a commit to paperMoose/openclaw that referenced this pull request Feb 18, 2026
Add SecretAgentProvider that implements the SecretProvider interface
by shelling out to the secret-agent CLI. Secrets never enter Node.js
process memory beyond the returned value.

Features:
- getSecret via `secret-agent exec --env` (avoids exposing values in ps)
- setSecret via `secret-agent import --replace`
- Bucket support for environment separation (prod/dev/staging)
- Custom binary path configuration
- Provider-level caching with configurable TTL
- Full test suite with mocked child_process

Resolves part of openclaw#14411, builds on openclaw#16663.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Feb 22, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Feb 23, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Mar 13, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

@akoscz

akoscz commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Hi @amor71 — wanted to close the loop on this thread and your sibling PRs (#43640, #43641, #43643, #43644, #43645, #43646).

The parallel SecretProvider interface architecture in this PR set was the right shape for a single vendor but didn't compose — each new backend required additions to the parallel system, and core's existing src/secrets/ infrastructure stayed unaware. That's why this set was closed back in March.

The alternative architecture is now in #72548 — a manifest-first plugin SDK seam that hooks into the existing src/secrets/ resolver via a one-line dispatch fall-through. New SecretRef sources land as plugins (extensions/secrets-<vendor>/) declaring contracts.secretProviders: ["<source-id>"] in their manifest and shipping a secret-provider.ts factory. No core changes for new sources.

Your resolver bodies port over with mostly mechanical changes. The implementations you wrote (GCP at #16663, AWS/Azure/Vault/1Password across the sibling PRs) are still useful — the SDK calls, payload decoding, error mapping, and stale-while-revalidate logic all carry. What changes is the wrapping shell: drop the src/config/secret-resolution.ts parallel-system bits, wrap each resolver in a createXxxSecretProvider() factory implementing SecretProviderPlugin from openclaw/plugin-sdk/secret-provider, and add the manifest + index.ts + package.json per the templates in #72548 (extensions/secrets-gcp/ and extensions/secrets-keyring/).

If you'd like to revisit any of the vendor work as plugins on the new seam, happy to review. The branch (https://github.com/akoscz/openclaw/tree/feature/secrets-provider-sdk) has both reference plugins to copy from. Each vendor would land as its own focused PR — much smaller diffs than the original set.

Thanks again for the original work; it directly informed the shape of the seam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime scripts Repository scripts size: XL stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add native secrets management integration (AWS Secrets Manager, Vault, etc.)

4 participants