feat(credential-sharing): implement the Credential Sharing OpenSpec (M1-M3)

New @logicsrc/plugin-credential-sharing: a provider-neutral secret-sync engine
with env/.env, Doppler, Railway, and GitHub Secrets adapters behind one
CredentialProvider contract.

- engine: inspect -> diff -> plan -> approve -> sync -> rollback -> audit/export
- dry-run is the default for sync; --approve writes; destructive changes gated
- fingerprint-based diffs (salted SHA-256); raw values never printed or stored in
  plans/runs/audit; rollback pre-image kept in a 0600 .logicsrc vault (gitignored)
- github-secrets is write-only for values (sealed-box via libsodium), so it cannot
  be a sync source or value-restoring rollback target
- CLI: real `logicsrc credentials <providers|inspect|diff|plan|approve|sync|
  rollback|audit|export>` (replaces the prior stub)
- 4 JSON schemas registered in @logicsrc/validators
- flip logicsrc.com/credential-sharing band from coming-soon to available
- 37 tests pass; full env->env lifecycle verified; artifacts schema-validate

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Anthony Ettinger 2026-06-27 15:24:30 +00:00
parent 6e7f44612a
commit cf73fe5af2
30 changed files with 1849 additions and 38 deletions

View file

@ -0,0 +1,66 @@
import type { PluginDefinition } from "@logicsrc/plugin-core";
import { credentialSharingManifest } from "./manifest.js";
import { CredentialEngine, type CredentialEngineOptions } from "./engine.js";
import { listCredentialProviderManifests } from "./providers/index.js";
export const credentialSharingPlugin: PluginDefinition = {
manifest: credentialSharingManifest,
configDefaults: {
enabled: true,
default_policy: "approval_required_for_destructive",
credential_home: "${LOGICSRC_CREDENTIAL_HOME}"
},
routes: [
{ method: "GET", path: "/api/credentials/providers", capability: "credentials.providers.list" },
{ method: "GET", path: "/api/credentials/inspect", capability: "credentials.inspect" },
{ method: "POST", path: "/api/credentials/diff", capability: "credentials.diff" },
{ method: "POST", path: "/api/credentials/plans", capability: "credentials.plan" },
{ method: "POST", path: "/api/credentials/plans/:id/approve", capability: "credentials.approve" },
{ method: "POST", path: "/api/credentials/plans/:id/sync", capability: "credentials.sync" },
{ method: "POST", path: "/api/credentials/runs/:id/rollback", capability: "credentials.rollback" },
{ method: "GET", path: "/api/credentials/runs/:id/audit", capability: "credentials.audit.read" }
],
permissions: [
"credentials:inspect",
"credentials:diff",
"credentials:plan",
"credentials:approve",
"credentials:sync",
"credentials:rollback",
"credentials:audit:read"
],
tuiPanels: [{ id: "credential-sharing", title: "Credential Sharing" }]
};
/** Factory mirroring the LogicSRC Credential Sharing SDK spec. */
export function createCredentialEngine(options: CredentialEngineOptions = {}): CredentialEngine {
return new CredentialEngine(options);
}
/** Provider listing without constructing an engine (used by the CLI `providers` command). */
export function listCredentialProviders() {
return listCredentialProviderManifests();
}
export { credentialSharingManifest };
export { CredentialEngine, DEFAULT_CREDENTIAL_POLICY, endpointLabel } from "./engine.js";
export type { CredentialEngineOptions } from "./engine.js";
export {
credentialProviders,
credentialProviderRegistry,
listCredentialProviderManifests,
envProvider,
dopplerProvider,
railwayProvider,
githubSecretsProvider,
parseEnv,
applyEnv
} from "./providers/index.js";
export {
createFileCredentialStore,
createMemoryCredentialStore,
defaultCredentialHome,
type CredentialStore
} from "./store.js";
export { fingerprintValue, fingerprintsEqual } from "./fingerprint.js";
export * from "./types.js";