Repository navigation
fix(ociplugins): try every configured key when the command names none - #891
Conversation
Marketplace installs (and any oci:// command without ?pubkey=) were only
checked with the first default key, the embedded Tyk key, so a plugin
signed with a key the operator added (OCI_PLUGINS_PUBKEY_*) failed unless
its install command was edited.
An unpinned check now tries each configured default key in order, the
Tyk key first, for the index and then the platform-manifest fallback, and
records the key that verified. A cache hit without ?pubkey= accepts the
entry while that key is still configured, so removing a key revokes the
plugins it verified; entries from earlier releases ("" recorded) stay
valid. ?pubkey= keeps its single-key behaviour. The Community Edition
path is unchanged.
Bead: midsommar-clean-ucxi
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This PR fixes an issue where OCI plugins installed without a specified public key (e.g., from the marketplace) were only checked against the first configured key. The change updates the signature verification logic to try every configured public key in order until one succeeds. This allows administrators to trust third-party plugins by adding the publisher's key to the configuration, without needing to modify the plugin's installation command. Additionally, the key that successfully verifies a plugin is now recorded in the cache. When loading a plugin from the cache, this recorded key is checked against the current configuration. This ensures that if a public key is removed from the configuration, any plugins that were verified by it are effectively revoked and will not be loaded from the cache. Files Changed AnalysisThe changes are well-structured across logic, testing, and documentation:
Architecture & Impact Assessment
Verification FlowsequenceDiagram
participant User
participant OCIClient
participant Verifier
participant Cache
alt Old Flow (Unpinned Plugin)
User->>OCIClient: FetchPlugin("oci://...")
OCIClient->>Verifier: VerifySignature(digest, defaultKey[0])
Verifier-->>OCIClient: Fails (if not signed by first key)
OCIClient-->>User: Error
end
alt New Flow (Unpinned Plugin)
User->>OCIClient: FetchPlugin("oci://...")
OCIClient->>OCIClient: signatureKeys() → [key1, key2, ...]
loop For each key
OCIClient->>Verifier: VerifySignature(digest, key)
alt Verification Succeeds
Verifier-->>OCIClient: Success
OCIClient->>Cache: StoreMetadata(..., verifiedByKey=key)
OCIClient-->>User: Success
break
end
end
alt All keys failed
OCIClient-->>User: Error (naming all keys tried)
end
end
end
Scope Discovery & Context ExpansionThe changes are concentrated in the This change improves security posture by introducing a mechanism to revoke trust. By removing a public key from the environment configuration, administrators can now ensure that any cached plugins signed with that key will no longer be loaded, which was not previously possible. Metadata
Powered by Visor from Probelabs Last updated: 2026-10-28T21:03:14.620Z | Triggered by: pr_opened | Commit: 57d3fef 💡 TIP: You can chat with Visor using |
✅ Architecture Check PassedNo architecture issues found – changes LGTM. Performance Issues (2)
✅ Architecture Check PassedNo architecture issues found – changes LGTM. \n\nPerformance Issues (2)
No quality issues found – changes LGTM. Powered by Visor from Probelabs Last updated: 2026-10-28T21:03:11.432Z | Triggered by: pr_opened | Commit: 57d3fef 💡 TIP: You can chat with Visor using |
Problem
A plugin installed from the marketplace (any
oci://command without?pubkey=) was checked only against the first default key, the embedded Tyk key. A third-party plugin signed with a key the operator had added (OCI_PLUGINS_PUBKEY_*) failed verification unless the admin edited the install command to add?pubkey=<ID>. Found while vetting the Next Moca plugin (TykTechnologies/tyk-ai-studio-plugins-ce#2).Admins should still have to add third-party keys explicitly; they shouldn't have to change the install command.
Change
pkg/ociplugins/client.go): with no?pubkey=, each configured default key is tried in order, the Tyk key first, for the index and for the platform-manifest fallback. The key that verified is recorded in the cache entry and logged aspublic_key. If none verifies, the error names every key tried.?pubkey=keeps its single-key behaviour and now also restricts a plugin to that one key.plugins-security.md,plugins-deployment.md,features/PluginSecurity.md("Which key is tried"),features/PluginMarketplace.md,microgateway/docs/oci-plugin-workflow.md, and the 2.3.0 changelog.Tests
New
pkg/ociplugins/unpinned_keys_test.go:?pubkey=; a Tyk-signed one tries only the Tyk key.TestSignatureKeysandTestDefaultKeyIDsResolve.go test ./pkg/ociplugins/... ./services/plugin_security/...passes after rebasing on main; theconfig,services(OCI/plugin) and microgatewayinternal/configandinternal/servicestests passed before the rebase.Bead:
midsommar-clean-ucxi. Follow-up filed asmidsommar-clean-0388(record the key's fingerprint, not only its name).🤖 Generated with Claude Code