Skip to content

Commit 6037a74

Browse files
sallyomjoshavant
andauthored
Add plugin manifest contract for SecretRef provider integrations (#82326)
* secret-provider-integrations Signed-off-by: sallyom <somalley@redhat.com> * feat(secrets): configure plugin provider presets * secrets: use plugin-managed provider refs Signed-off-by: sallyom <somalley@redhat.com> * fix secretref auth profile service env * test secret provider integration e2e * fix secretref plugin config service env * fix secret provider preset schema alignment * stabilize secret provider service proof * validate secret provider plugin integrations * harden secret provider resolver paths * scope secret provider config validation * stabilize openai secret provider proof * fix secret provider metadata proof * stabilize config baseline proof * fix secret provider e2e lint --------- Signed-off-by: sallyom <somalley@redhat.com> Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
1 parent f123547 commit 6037a74

37 files changed

Lines changed: 4437 additions & 93 deletions
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
c80dea63b0a3786c8999d06aae62c110786f440b4d6748f9838577aaa2816971 config-baseline.json
2-
948323a1507817b6580ed976f9f9449239008f40283cc7e6005148ecf0ca4582 config-baseline.core.json
3-
f833ffca6bd88162f062bbea4f0eede783373f46674ebbfc3a390c80353930a2 config-baseline.channel.json
4-
bc38b58b67132401a030b3b3a77efdb6c88f207ea1fab9abcb4599e1f9552dda config-baseline.plugin.json
1+
ac5e91a6adaf02491d2ff6b983f054c813972da3bf79db68cd1d10887a22c594 config-baseline.json
2+
023e3b85ee79e85f90257e65a1376b1212cf534b6a9cff4b4388c9092e846549 config-baseline.core.json
3+
a9102c0611b8170fac37853cc31771810f31757a9e3b2c6796bbd9625f9b9206 config-baseline.channel.json
4+
2f018852d9682871dd22f0920cafc8994a6c0952e8101229210efa6103ae9536 config-baseline.plugin.json
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
59de21361cab0622926ad313caf3f8dc43c28d420a82ba060680ecc30c472453 plugin-sdk-api-baseline.json
2-
05adee9037669db4e834d1a0ca9705d5d94df770083862ab149d2f3e559010d2 plugin-sdk-api-baseline.jsonl
1+
74c6b635c822358e61473a5b1bf7e6786592c459289057db2fddf807ffa022ec plugin-sdk-api-baseline.json
2+
4db87f9b57209632cd3887d791277f6c30c4a894b09785a2b51cb50cb5aedb78 plugin-sdk-api-baseline.jsonl

docs/gateway/secrets.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ Define providers under `secrets.providers`:
183183
passEnv: ["PATH", "VAULT_ADDR"],
184184
jsonOnly: true,
185185
},
186+
"team-secrets": {
187+
source: "exec",
188+
pluginIntegration: {
189+
pluginId: "acme-secrets",
190+
integrationId: "secret-store",
191+
},
192+
},
186193
},
187194
defaults: {
188195
env: "default",
@@ -219,6 +226,11 @@ Define providers under `secrets.providers`:
219226
- Pair `allowSymlinkCommand` with `trustedDirs` for package-manager paths (for example `["/opt/homebrew"]`).
220227
- Supports timeout, no-output timeout, output byte limits, env allowlist, and trusted dirs.
221228
- Windows fail-closed note: if ACL verification is unavailable for the command path, resolution fails. For trusted paths only, set `allowInsecurePath: true` on that provider to bypass path security checks.
229+
- Plugin-managed exec providers can use `pluginIntegration` instead of
230+
copied `command`/`args`. OpenClaw resolves the current command details
231+
from the installed plugin manifest during startup/reload. If the plugin is
232+
disabled, removed, untrusted, or no longer declares the integration,
233+
active SecretRefs using that provider fail closed.
222234

223235
Request payload (stdin):
224236

docs/plugins/manifest.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ or npm install metadata. Those belong in your plugin code and `package.json`.
169169
| `modelIdNormalization` | No | `object` | Provider-owned model-id alias/prefix cleanup that must run before provider runtime loads. |
170170
| `providerEndpoints` | No | `object[]` | Manifest-owned endpoint host/baseUrl metadata for provider routes that core must classify before provider runtime loads. |
171171
| `providerRequest` | No | `object` | Cheap provider-family and request-compatibility metadata used by generic request policy before provider runtime loads. |
172+
| `secretProviderIntegrations` | No | `Record<string, object>` | Declarative SecretRef exec provider presets that setup or install surfaces can offer without hardcoding provider-specific integrations in core. |
172173
| `cliBackends` | No | `string[]` | CLI inference backend ids owned by this plugin. Used for startup auto-activation from explicit config refs. |
173174
| `syntheticAuthRefs` | No | `string[]` | Provider or CLI backend refs whose plugin-owned synthetic auth hook should be probed during cold model discovery before runtime loads. |
174175
| `nonSecretAuthMarkers` | No | `string[]` | Bundled-plugin-owned placeholder API key values that represent non-secret local, OAuth, or ambient credential state. |
@@ -1080,6 +1081,72 @@ Provider fields:
10801081
| `compatibilityFamily` | `"moonshot"` | Optional provider-family compatibility bucket for shared request helpers. |
10811082
| `openAICompletions` | `object` | OpenAI-compatible completions request flags, currently `supportsStreamingUsage`. |
10821083

1084+
## secretProviderIntegrations reference
1085+
1086+
Use `secretProviderIntegrations` when a plugin can publish a reusable SecretRef
1087+
exec provider preset. OpenClaw reads this metadata before plugin runtime loads,
1088+
stores plugin ownership in `secrets.providers.<alias>.pluginIntegration`, and
1089+
leaves actual secret resolution to the SecretRef runtime.
1090+
Presets are exposed only for bundled plugins and installed plugins discovered
1091+
from the managed plugin install roots, such as git and ClawHub installs.
1092+
1093+
```json
1094+
{
1095+
"secretProviderIntegrations": {
1096+
"secret-store": {
1097+
"providerAlias": "team-secrets",
1098+
"displayName": "Team secrets",
1099+
"source": "exec",
1100+
"command": "${node}",
1101+
"args": ["./bin/resolve-secrets.mjs"]
1102+
}
1103+
}
1104+
}
1105+
```
1106+
1107+
The map key is the integration id. If `providerAlias` is omitted, OpenClaw uses
1108+
the integration id as the SecretRef provider alias. Provider aliases must match
1109+
the normal SecretRef provider alias pattern, for example `team-secrets` or
1110+
`onepassword-work`.
1111+
1112+
When an operator selects the preset, OpenClaw writes a provider reference like:
1113+
1114+
```json
1115+
{
1116+
"secrets": {
1117+
"providers": {
1118+
"team-secrets": {
1119+
"source": "exec",
1120+
"pluginIntegration": {
1121+
"pluginId": "acme-secrets",
1122+
"integrationId": "secret-store"
1123+
}
1124+
}
1125+
}
1126+
}
1127+
}
1128+
```
1129+
1130+
At startup/reload, OpenClaw resolves that provider by loading current plugin
1131+
manifest metadata, checking that the owning plugin is installed and active, and
1132+
materializing the exec command from the manifest. Disabling or removing the
1133+
plugin revokes the provider for active SecretRefs. Operators who want standalone
1134+
exec configuration can still write manual `command`/`args` providers directly.
1135+
1136+
Only `source: "exec"` presets are currently supported. `command` must be
1137+
`${node}`, and `args[0]` must be a `./` plugin-root-relative resolver script.
1138+
OpenClaw materializes it at startup/reload to the current Node executable and
1139+
the absolute in-plugin script path. Node options such as `--require`, `--import`,
1140+
`--loader`, `--env-file`, `--eval`, and `--print` are not part of the manifest
1141+
preset contract. Operators who need non-Node commands can configure standalone
1142+
manual exec providers directly.
1143+
1144+
OpenClaw derives `trustedDirs` for manifest presets from the plugin root and,
1145+
for `${node}` presets, the current Node executable directory. Manifest-authored
1146+
`trustedDirs` are ignored. Other exec provider options such as `timeoutMs`,
1147+
`maxOutputBytes`, `jsonOnly`, `env`, `passEnv`, and `allowInsecurePath` pass
1148+
through to the normal SecretRef exec provider config.
1149+
10831150
## modelPricing reference
10841151

10851152
Use `modelPricing` when a provider needs control-plane pricing behavior before

docs/plugins/sdk-subpaths.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ and pairing-path families.
192192
| `plugin-sdk/allow-from` | `formatAllowFromLowercase` |
193193
| `plugin-sdk/channel-secret-runtime` | Narrow secret-contract collection helpers for channel/plugin secret surfaces |
194194
| `plugin-sdk/secret-ref-runtime` | Narrow `coerceSecretRef` and SecretRef typing helpers for secret-contract/config parsing |
195+
| `plugin-sdk/secret-provider-integration` | Type-only SecretRef provider integration manifest and preset contracts for plugins that publish external secret provider presets |
195196
| `plugin-sdk/security-runtime` | Shared trust, DM gating, root-bounded file/path helpers including create-only writes, sync/async atomic file replacement, sibling temp writes, cross-device move fallback, private file-store helpers, symlink-parent guards, external-content, sensitive text redaction, constant-time secret comparison, and secret-collection helpers |
196197
| `plugin-sdk/ssrf-policy` | Host allowlist and private-network SSRF policy helpers |
197198
| `plugin-sdk/ssrf-dispatcher` | Narrow pinned-dispatcher helpers without the broad infra runtime surface |

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,10 @@
545545
"types": "./dist/plugin-sdk/secret-ref-runtime.d.ts",
546546
"default": "./dist/plugin-sdk/secret-ref-runtime.js"
547547
},
548+
"./plugin-sdk/secret-provider-integration": {
549+
"types": "./dist/plugin-sdk/secret-provider-integration.d.ts",
550+
"default": "./dist/plugin-sdk/secret-provider-integration.js"
551+
},
548552
"./plugin-sdk/secret-file-runtime": {
549553
"types": "./dist/plugin-sdk/secret-file-runtime.d.ts",
550554
"default": "./dist/plugin-sdk/secret-file-runtime.js"

0 commit comments

Comments
 (0)