Skip to content

feat(plugins): add signed registry index client - #1726

Open
developerkunal wants to merge 1 commit into
DXCDT-2601/manifest-schemafrom
DXCDT-2602/registry-client
Open

developerkunal wants to merge 1 commit into
DXCDT-2601/manifest-schemafrom
DXCDT-2602/registry-client

Conversation

@developerkunal

@developerkunal developerkunal commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

🔧 Changes

Adds internal/plugins/registry, a client that fetches the plugin registry index, refuses anything that is not correctly signed, fresh and newer than what this machine has already seen, and keeps a verified copy on disk. This is a library only, so nothing changes for users yet.

Fail closed by default. A normal build embeds no trusted key yet, so every refresh fails until the production key is added under DXCDT-2611. Keys are embedded in the binary, and no environment variable, config entry or flag can add or replace one.

Verified before the index is used

  • An Ed25519 signature over the raw index bytes, with the key looked up by key ID in the embedded set.
  • The format version, the schema, expiry, and a rollback check against the highest index version accepted before.
  • Duplicate JSON keys and unsorted permission lists are rejected, and each permissionsHash is recomputed with the manifest algorithm.
  • Per-plugin files an index points to are pinned by hash, size capped and validated like the index.

Client behavior

  • A failed refresh leaves the cache as it was. Load verifies the cache every time and never uses the network.
  • When the network is unreachable, the registry serves an older index, or another process holds the lock, EnsureFresh falls back to the verified cache and marks it stale without advancing the last refresh time. A registry that keeps failing therefore makes installed plugins unrunnable once the offline grace period (30 days by default) passes. A signature failure is never treated as offline.
  • All fetches are https only, including every redirect hop, with size caps.

Config. The config gains an optional registries list. The built in auth0 registry is always there, a configured auth0 entry can only change its URL, and any other name is rejected because custom registries are not supported yet.

Existing code. ParseManifest and ParseInstalledManifest now reject duplicate JSON keys, which is a deliberate stricter behavior.

📚 References

DXCDT-2602. This is part of the plugin framework stack of 11 PRs and builds on the PR below it, DXCDT-2601.

🔬 Testing

The new code is covered by unit tests.

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@developerkunal
developerkunal requested a review from a team as a code owner October 24, 2026 14:47
Comment thread internal/plugins/registry/registrytest/server.go
Fetch the plugin registry index, refuse anything that is not correctly
signed, fresh and newer than what this machine has seen, and keep a
verified copy on disk. A normal build trusts no keys yet, so it fails
closed until the production key is embedded.

- Ed25519 signature over the raw index bytes, embedded keys looked up by
  key ID, rollback and expiry checks, a revocation and deprecation list,
  and a policy block with offline grace and check interval.
- Index and per-plugin files are validated against an embedded schema, with
  duplicate keys, case variant keys and unsorted permission lists rejected,
  and each version's permissions hash recomputed with the manifest algorithm.
- A client with Refresh, Load and EnsureFresh. Files are staged and renamed
  in a fail closed order under a cross process file lock, the cache is
  verified again on every load, and a verified cache is used when the
  network, a rollback or a busy lock prevents a refresh.
- Registries list in the CLI config with the built in auth0 entry, https
  only fetches including every redirect hop, and size caps on every read.
- registrytest fixtures and a plugintest build tag that trusts a throwaway
  key and allows loopback http, so the flow can be tested without
  publishing. Contract vectors are shipped for the catalog pipeline.
- Shared helpers in the plugins package: strict JSON decoding that rejects
  duplicate keys, a normalized permissions function and a platform lookup.
@developerkunal
developerkunal force-pushed the DXCDT-2602/registry-client branch from 522d4e7 to 14e0f88 Compare October 24, 2026 15:30

This branch has not been deployed

No deployments
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