@vibesdotdev/secrets 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -0
- package/SPEC.md +47 -0
- package/dist/cli/check/schemas/check-result.d.ts +9 -0
- package/dist/cli/check/schemas/check-result.d.ts.map +1 -0
- package/dist/cli/check/schemas/check-result.js +2 -0
- package/dist/cli/check/schemas/check-result.js.map +1 -0
- package/dist/cli/check/secrets.check.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/check/secrets.check.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/check/secrets.check.cli-command.descriptor.js +19 -0
- package/dist/cli/check/secrets.check.cli-command.descriptor.js.map +1 -0
- package/dist/cli/check/secrets.check.cli-command.impl.d.ts +5 -0
- package/dist/cli/check/secrets.check.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/check/secrets.check.cli-command.impl.js +135 -0
- package/dist/cli/check/secrets.check.cli-command.impl.js.map +1 -0
- package/dist/cli/export/secrets.export.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/export/secrets.export.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/export/secrets.export.cli-command.descriptor.js +20 -0
- package/dist/cli/export/secrets.export.cli-command.descriptor.js.map +1 -0
- package/dist/cli/export/secrets.export.cli-command.impl.d.ts +5 -0
- package/dist/cli/export/secrets.export.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/export/secrets.export.cli-command.impl.js +104 -0
- package/dist/cli/export/secrets.export.cli-command.impl.js.map +1 -0
- package/dist/cli/hooks/pre-commit-secrets.d.ts +2 -0
- package/dist/cli/hooks/pre-commit-secrets.d.ts.map +1 -0
- package/dist/cli/hooks/pre-commit-secrets.js +68 -0
- package/dist/cli/hooks/pre-commit-secrets.js.map +1 -0
- package/dist/cli/import/secrets.import.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/import/secrets.import.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/import/secrets.import.cli-command.descriptor.js +19 -0
- package/dist/cli/import/secrets.import.cli-command.descriptor.js.map +1 -0
- package/dist/cli/import/secrets.import.cli-command.impl.d.ts +5 -0
- package/dist/cli/import/secrets.import.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/import/secrets.import.cli-command.impl.js +155 -0
- package/dist/cli/import/secrets.import.cli-command.impl.js.map +1 -0
- package/dist/cli/list/secrets.list.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/list/secrets.list.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/list/secrets.list.cli-command.descriptor.js +18 -0
- package/dist/cli/list/secrets.list.cli-command.descriptor.js.map +1 -0
- package/dist/cli/list/secrets.list.cli-command.impl.d.ts +5 -0
- package/dist/cli/list/secrets.list.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/list/secrets.list.cli-command.impl.js +61 -0
- package/dist/cli/list/secrets.list.cli-command.impl.js.map +1 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.descriptor.js +16 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.descriptor.js.map +1 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.impl.d.ts +5 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.impl.js +10 -0
- package/dist/cli/pre-commit/secrets.pre-commit-check.cli-command.impl.js.map +1 -0
- package/dist/cli/pull/secrets.pull.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/pull/secrets.pull.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/pull/secrets.pull.cli-command.descriptor.js +20 -0
- package/dist/cli/pull/secrets.pull.cli-command.descriptor.js.map +1 -0
- package/dist/cli/pull/secrets.pull.cli-command.impl.d.ts +5 -0
- package/dist/cli/pull/secrets.pull.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/pull/secrets.pull.cli-command.impl.js +76 -0
- package/dist/cli/pull/secrets.pull.cli-command.impl.js.map +1 -0
- package/dist/cli/push/secrets.push.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/push/secrets.push.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/push/secrets.push.cli-command.descriptor.js +22 -0
- package/dist/cli/push/secrets.push.cli-command.descriptor.js.map +1 -0
- package/dist/cli/push/secrets.push.cli-command.impl.d.ts +5 -0
- package/dist/cli/push/secrets.push.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/push/secrets.push.cli-command.impl.js +109 -0
- package/dist/cli/push/secrets.push.cli-command.impl.js.map +1 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.descriptor.js +19 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.descriptor.js.map +1 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.impl.d.ts +5 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.impl.js +85 -0
- package/dist/cli/reveal/secrets.reveal.cli-command.impl.js.map +1 -0
- package/dist/cli/secrets.cli-group.descriptor.d.ts +4 -0
- package/dist/cli/secrets.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/secrets.cli-group.descriptor.js +11 -0
- package/dist/cli/secrets.cli-group.descriptor.js.map +1 -0
- package/dist/cli/set/secrets.set.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/set/secrets.set.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/set/secrets.set.cli-command.descriptor.js +21 -0
- package/dist/cli/set/secrets.set.cli-command.descriptor.js.map +1 -0
- package/dist/cli/set/secrets.set.cli-command.impl.d.ts +5 -0
- package/dist/cli/set/secrets.set.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/set/secrets.set.cli-command.impl.js +59 -0
- package/dist/cli/set/secrets.set.cli-command.impl.js.map +1 -0
- package/dist/cli/shared/resolve-environment.d.ts +14 -0
- package/dist/cli/shared/resolve-environment.d.ts.map +1 -0
- package/dist/cli/shared/resolve-environment.js +45 -0
- package/dist/cli/shared/resolve-environment.js.map +1 -0
- package/dist/cli/unset/secrets.unset.cli-command.descriptor.d.ts +4 -0
- package/dist/cli/unset/secrets.unset.cli-command.descriptor.d.ts.map +1 -0
- package/dist/cli/unset/secrets.unset.cli-command.descriptor.js +20 -0
- package/dist/cli/unset/secrets.unset.cli-command.descriptor.js.map +1 -0
- package/dist/cli/unset/secrets.unset.cli-command.impl.d.ts +5 -0
- package/dist/cli/unset/secrets.unset.cli-command.impl.d.ts.map +1 -0
- package/dist/cli/unset/secrets.unset.cli-command.impl.js +31 -0
- package/dist/cli/unset/secrets.unset.cli-command.impl.js.map +1 -0
- package/dist/docs/backends.docs.descriptor.d.ts +4 -0
- package/dist/docs/backends.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/backends.docs.descriptor.js +149 -0
- package/dist/docs/backends.docs.descriptor.js.map +1 -0
- package/dist/docs/encryption.docs.descriptor.d.ts +4 -0
- package/dist/docs/encryption.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/encryption.docs.descriptor.js +163 -0
- package/dist/docs/encryption.docs.descriptor.js.map +1 -0
- package/dist/docs/env-file.docs.descriptor.d.ts +4 -0
- package/dist/docs/env-file.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/env-file.docs.descriptor.js +207 -0
- package/dist/docs/env-file.docs.descriptor.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/kinds/index.d.ts +4 -0
- package/dist/kinds/index.d.ts.map +1 -0
- package/dist/kinds/index.js +3 -0
- package/dist/kinds/index.js.map +1 -0
- package/dist/kinds/schemas/store.schema.d.ts +49 -0
- package/dist/kinds/schemas/store.schema.d.ts.map +1 -0
- package/dist/kinds/schemas/store.schema.js +34 -0
- package/dist/kinds/schemas/store.schema.js.map +1 -0
- package/dist/kinds/schemas/store.types.d.ts +28 -0
- package/dist/kinds/schemas/store.types.d.ts.map +1 -0
- package/dist/kinds/schemas/store.types.js +2 -0
- package/dist/kinds/schemas/store.types.js.map +1 -0
- package/dist/kinds/store.interface.d.ts +2 -0
- package/dist/kinds/store.interface.d.ts.map +1 -0
- package/dist/kinds/store.interface.js +2 -0
- package/dist/kinds/store.interface.js.map +1 -0
- package/dist/kinds/store.kind.d.ts +10 -0
- package/dist/kinds/store.kind.d.ts.map +1 -0
- package/dist/kinds/store.kind.js +36 -0
- package/dist/kinds/store.kind.js.map +1 -0
- package/dist/kinds/store.schema.d.ts +2 -0
- package/dist/kinds/store.schema.d.ts.map +1 -0
- package/dist/kinds/store.schema.js +2 -0
- package/dist/kinds/store.schema.js.map +1 -0
- package/dist/manifest/canonical.d.ts +30 -0
- package/dist/manifest/canonical.d.ts.map +1 -0
- package/dist/manifest/canonical.js +313 -0
- package/dist/manifest/canonical.js.map +1 -0
- package/dist/manifest/import-manifest.schema.d.ts +77 -0
- package/dist/manifest/import-manifest.schema.d.ts.map +1 -0
- package/dist/manifest/import-manifest.schema.js +55 -0
- package/dist/manifest/import-manifest.schema.js.map +1 -0
- package/dist/manifest/index.d.ts +3 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +3 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/requirements/index.d.ts +2 -0
- package/dist/requirements/index.d.ts.map +1 -0
- package/dist/requirements/index.js +2 -0
- package/dist/requirements/index.js.map +1 -0
- package/dist/requirements/resolver.d.ts +52 -0
- package/dist/requirements/resolver.d.ts.map +1 -0
- package/dist/requirements/resolver.js +196 -0
- package/dist/requirements/resolver.js.map +1 -0
- package/dist/requirements/schemas/requirements.d.ts +27 -0
- package/dist/requirements/schemas/requirements.d.ts.map +1 -0
- package/dist/requirements/schemas/requirements.js +2 -0
- package/dist/requirements/schemas/requirements.js.map +1 -0
- package/dist/secrets.plugin.d.ts +8 -0
- package/dist/secrets.plugin.d.ts.map +1 -0
- package/dist/secrets.plugin.js +59 -0
- package/dist/secrets.plugin.js.map +1 -0
- package/package.json +108 -0
- package/src/cli/check/schemas/check-result.ts +8 -0
- package/src/cli/check/secrets.check.cli-command.descriptor.ts +21 -0
- package/src/cli/check/secrets.check.cli-command.impl.ts +163 -0
- package/src/cli/export/secrets.export.cli-command.descriptor.ts +22 -0
- package/src/cli/export/secrets.export.cli-command.impl.ts +139 -0
- package/src/cli/hooks/pre-commit-secrets.ts +73 -0
- package/src/cli/import/secrets.import.cli-command.descriptor.ts +21 -0
- package/src/cli/import/secrets.import.cli-command.impl.ts +178 -0
- package/src/cli/list/secrets.list.cli-command.descriptor.ts +21 -0
- package/src/cli/list/secrets.list.cli-command.impl.ts +79 -0
- package/src/cli/pre-commit/secrets.pre-commit-check.cli-command.descriptor.ts +18 -0
- package/src/cli/pre-commit/secrets.pre-commit-check.cli-command.impl.ts +11 -0
- package/src/cli/pull/secrets.pull.cli-command.descriptor.ts +22 -0
- package/src/cli/pull/secrets.pull.cli-command.impl.ts +103 -0
- package/src/cli/push/secrets.push.cli-command.descriptor.ts +24 -0
- package/src/cli/push/secrets.push.cli-command.impl.ts +149 -0
- package/src/cli/reveal/secrets.reveal.cli-command.descriptor.ts +21 -0
- package/src/cli/reveal/secrets.reveal.cli-command.impl.ts +108 -0
- package/src/cli/secrets.cli-group.descriptor.ts +13 -0
- package/src/cli/set/secrets.set.cli-command.descriptor.ts +23 -0
- package/src/cli/set/secrets.set.cli-command.impl.ts +77 -0
- package/src/cli/shared/resolve-environment.ts +57 -0
- package/src/cli/unset/secrets.unset.cli-command.descriptor.ts +22 -0
- package/src/cli/unset/secrets.unset.cli-command.impl.ts +41 -0
- package/src/docs/backends.docs.descriptor.ts +151 -0
- package/src/docs/encryption.docs.descriptor.ts +165 -0
- package/src/docs/env-file.docs.descriptor.ts +209 -0
- package/src/index.ts +35 -0
- package/src/kinds/index.ts +12 -0
- package/src/kinds/schemas/store.schema.ts +47 -0
- package/src/kinds/schemas/store.types.ts +35 -0
- package/src/kinds/store.interface.ts +1 -0
- package/src/kinds/store.kind.ts +52 -0
- package/src/kinds/store.schema.ts +8 -0
- package/src/manifest/canonical.ts +324 -0
- package/src/manifest/import-manifest.schema.ts +63 -0
- package/src/manifest/index.ts +12 -0
- package/src/requirements/index.ts +6 -0
- package/src/requirements/resolver.ts +216 -0
- package/src/requirements/schemas/requirements.ts +29 -0
- package/src/secrets.plugin.ts +65 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secrets Store Descriptor Schema
|
|
3
|
+
*
|
|
4
|
+
* Defines the structure for secrets/store kind descriptors.
|
|
5
|
+
* Each descriptor represents a secrets storage backend
|
|
6
|
+
* (env-file, encrypted-local, cloudflare-api, vault).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as z from 'zod/v4';
|
|
10
|
+
|
|
11
|
+
export const EnvironmentTierSchema = z.enum(['local', 'dev', 'staging', 'production']);
|
|
12
|
+
|
|
13
|
+
export type EnvironmentTier = z.infer<typeof EnvironmentTierSchema>;
|
|
14
|
+
|
|
15
|
+
export const SecretsBackendSchema = z.enum([
|
|
16
|
+
'env-file',
|
|
17
|
+
'encrypted-local',
|
|
18
|
+
'cloudflare-api',
|
|
19
|
+
'cloudflare-secrets-store',
|
|
20
|
+
'vault'
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
export type SecretsBackend = z.infer<typeof SecretsBackendSchema>;
|
|
24
|
+
|
|
25
|
+
export const SecretsStoreDescriptorSchema = z.object({
|
|
26
|
+
id: z.string().min(1),
|
|
27
|
+
kind: z.literal('secrets/store'),
|
|
28
|
+
name: z.string().optional(),
|
|
29
|
+
description: z.string().optional(),
|
|
30
|
+
tags: z.array(z.string()).optional(),
|
|
31
|
+
enabled: z.boolean().optional(),
|
|
32
|
+
hardware: z.array(z.string()).optional(),
|
|
33
|
+
|
|
34
|
+
/** Backend type for this store */
|
|
35
|
+
backend: SecretsBackendSchema,
|
|
36
|
+
|
|
37
|
+
/** Environment tiers this store operates on */
|
|
38
|
+
tiers: z.array(EnvironmentTierSchema).min(1),
|
|
39
|
+
|
|
40
|
+
/** Resolution priority (higher wins for write ops) */
|
|
41
|
+
priority: z.number().int().default(0),
|
|
42
|
+
|
|
43
|
+
/** Backend-specific configuration key-value pairs */
|
|
44
|
+
config: z.record(z.string(), z.string()).optional()
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export type SecretsStoreDescriptor = z.infer<typeof SecretsStoreDescriptorSchema>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { SecretsStoreDescriptor } from './store.schema';
|
|
2
|
+
|
|
3
|
+
/** A single entry in a secrets listing */
|
|
4
|
+
export interface SecretEntry {
|
|
5
|
+
/** Secret key name (e.g., VIBES_AUTH_SECRET) */
|
|
6
|
+
key: string;
|
|
7
|
+
/** Whether a value is stored for this key */
|
|
8
|
+
hasValue: boolean;
|
|
9
|
+
/** Backend source identifier */
|
|
10
|
+
source: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Interface all secrets store backends must implement */
|
|
14
|
+
export interface SecretsStoreImplementation {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly descriptor: SecretsStoreDescriptor;
|
|
17
|
+
|
|
18
|
+
/** List all secret keys stored for an environment */
|
|
19
|
+
list(environment: string): Promise<SecretEntry[]>;
|
|
20
|
+
|
|
21
|
+
/** Get a single secret value (undefined if not found) */
|
|
22
|
+
get(environment: string, key: string): Promise<string | undefined>;
|
|
23
|
+
|
|
24
|
+
/** Set a secret value for an environment */
|
|
25
|
+
set(environment: string, key: string, value: string): Promise<void>;
|
|
26
|
+
|
|
27
|
+
/** Remove a secret from an environment */
|
|
28
|
+
unset(environment: string, key: string): Promise<void>;
|
|
29
|
+
|
|
30
|
+
/** Get all secret key-value pairs for an environment */
|
|
31
|
+
getAll(environment: string): Promise<Record<string, string>>;
|
|
32
|
+
|
|
33
|
+
/** Set multiple secrets at once (merges with existing) */
|
|
34
|
+
setAll(environment: string, secrets: Record<string, string>): Promise<void>;
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { SecretEntry, SecretsStoreImplementation } from './schemas/store.types';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secrets Store Kind Definition
|
|
3
|
+
*
|
|
4
|
+
* Registers the secrets/store kind with the runtime.
|
|
5
|
+
* Resolution selects backends by environment tier and priority.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createRuntimeKind } from '@vibesdotdev/runtime/factory/kind';
|
|
9
|
+
import type { KindContext, RuntimeKindDescriptorRecord, RuntimeDescriptor } from '@vibesdotdev/runtime/schemas/kind';
|
|
10
|
+
import type { RuntimeScope } from '@vibesdotdev/runtime/schemas/scope';
|
|
11
|
+
import {
|
|
12
|
+
SecretsStoreDescriptorSchema,
|
|
13
|
+
type SecretsStoreDescriptor,
|
|
14
|
+
type EnvironmentTier
|
|
15
|
+
} from './store.schema';
|
|
16
|
+
import type { SecretsStoreImplementation } from './store.interface';
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the best secrets store for the current scope.
|
|
19
|
+
*
|
|
20
|
+
* Filters candidates by environment tier (from scope qualifiers),
|
|
21
|
+
* then picks the highest-priority match.
|
|
22
|
+
*
|
|
23
|
+
* No defaultImplementation — missing backends cause hard failure at resolve()
|
|
24
|
+
* time per the SPEC hard rule: "Missing-backend means hard failure."
|
|
25
|
+
*/
|
|
26
|
+
function resolveSecretsStore(
|
|
27
|
+
candidates: RuntimeDescriptor[],
|
|
28
|
+
scope: RuntimeScope,
|
|
29
|
+
_context: KindContext
|
|
30
|
+
): SecretsStoreDescriptor | undefined {
|
|
31
|
+
const typed = candidates as SecretsStoreDescriptor[];
|
|
32
|
+
if (typed.length === 0) return undefined;
|
|
33
|
+
if (typed.length === 1) return typed[0];
|
|
34
|
+
|
|
35
|
+
const envTier = (scope.qualifiers?.environmentTier ?? 'local') as EnvironmentTier;
|
|
36
|
+
const tierMatches = typed.filter((d) => d.tiers.includes(envTier));
|
|
37
|
+
const pool = tierMatches.length > 0 ? tierMatches : typed;
|
|
38
|
+
|
|
39
|
+
pool.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
40
|
+
return pool[0];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const secretsStoreKind = createRuntimeKind<
|
|
44
|
+
SecretsStoreDescriptor,
|
|
45
|
+
SecretsStoreImplementation,
|
|
46
|
+
KindContext
|
|
47
|
+
>({
|
|
48
|
+
id: 'secrets/store',
|
|
49
|
+
descriptorSchema: SecretsStoreDescriptorSchema,
|
|
50
|
+
resolve: resolveSecretsStore,
|
|
51
|
+
contexts: []
|
|
52
|
+
});
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vibes Secrets Import Manifest (canonical, value-free)
|
|
3
|
+
*
|
|
4
|
+
* Read by `vibes secrets import` to discover which keys to pull from which
|
|
5
|
+
* local root env files when bootstrapping the encrypted Vibes store. The
|
|
6
|
+
* manifest is reconciled against ground truth: every entry corresponds to a
|
|
7
|
+
* real `secret: true` env var declared by an app's deployment config (or, in
|
|
8
|
+
* auth-web's case, by its sub-manifest files).
|
|
9
|
+
*
|
|
10
|
+
* Sources:
|
|
11
|
+
* - `local-env` (`.env.local`) is the canonical machine-local store of
|
|
12
|
+
* every actual production-quality secret value: auth secrets, OAuth
|
|
13
|
+
* client secrets (GitHub / Google / Discord / Microsoft), Resend, the
|
|
14
|
+
* internal auth token, Stripe billing keys, etc.
|
|
15
|
+
* - `production-env` (`.env.production`) holds production-flavored
|
|
16
|
+
* non-secret config plus the operator's CF coordinates. Value-free here.
|
|
17
|
+
* - `manual` is a pseudo-source for keys that must be set through another
|
|
18
|
+
* channel (`vibes secrets set`, generated tokens, or pasted from a vault).
|
|
19
|
+
* The import command skips `manual` entries with a notice.
|
|
20
|
+
*
|
|
21
|
+
* Operator credentials (`CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID`,
|
|
22
|
+
* `CLOUDFLARE_SECRETS_STORE_ID`) are intentionally NOT in this manifest.
|
|
23
|
+
* They authenticate the operator's machine to push secrets into the store;
|
|
24
|
+
* they are never themselves pushed into the store.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import {
|
|
28
|
+
SecretsImportManifestSchema,
|
|
29
|
+
type SecretsImportManifest
|
|
30
|
+
} from './import-manifest.schema';
|
|
31
|
+
|
|
32
|
+
const manifest: SecretsImportManifest = SecretsImportManifestSchema.parse({
|
|
33
|
+
version: 1,
|
|
34
|
+
sources: {
|
|
35
|
+
'local-env': {
|
|
36
|
+
path: '.env.local',
|
|
37
|
+
purpose:
|
|
38
|
+
'Canonical machine-local secret values: auth, OAuth, billing, internal tokens'
|
|
39
|
+
},
|
|
40
|
+
'production-env': {
|
|
41
|
+
path: '.env.production',
|
|
42
|
+
purpose: 'Production-flavored non-secret config + CF operator coordinates'
|
|
43
|
+
},
|
|
44
|
+
'manual': {
|
|
45
|
+
purpose:
|
|
46
|
+
"Set via `vibes secrets set <KEY>` or generated by ops; not sourced from a local file"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
secrets: [
|
|
50
|
+
// --- Auth gateway (auth-web) — sourced from .env.local ----------------------
|
|
51
|
+
{
|
|
52
|
+
key: 'VIBES_AUTH_SECRET',
|
|
53
|
+
category: 'vibes-auth',
|
|
54
|
+
source: 'local-env',
|
|
55
|
+
required: true,
|
|
56
|
+
description: 'Better Auth signing secret (auth-web)'
|
|
57
|
+
},
|
|
58
|
+
// `VIBES_AUTH_DATABASE_URL` / `VIBES_AUTH_DATABASE_AUTH_TOKEN` are
|
|
59
|
+
// dev-only: production auth-web binds its own D1 database (`vibes-auth-db`)
|
|
60
|
+
// via the `DB` binding in `wrangler.jsonc`. The libsql/file fallback in
|
|
61
|
+
// `auth-web/src/server/persistence.ts` is for local dev only. We keep
|
|
62
|
+
// them in the manifest so `vibes secrets import` still picks them up
|
|
63
|
+
// for a working local store, but they're optional and never pushed to
|
|
64
|
+
// the production Secrets Store.
|
|
65
|
+
{
|
|
66
|
+
key: 'VIBES_AUTH_DATABASE_URL',
|
|
67
|
+
category: 'vibes-auth',
|
|
68
|
+
source: 'local-env',
|
|
69
|
+
required: false,
|
|
70
|
+
description: 'LibSQL/Turso connection URL for auth persistence (DEV ONLY — production uses D1)'
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: 'VIBES_AUTH_DATABASE_AUTH_TOKEN',
|
|
74
|
+
category: 'vibes-auth',
|
|
75
|
+
source: 'local-env',
|
|
76
|
+
aliases: ['DATABASE_AUTH_TOKEN'],
|
|
77
|
+
required: false,
|
|
78
|
+
description: 'LibSQL/Turso auth token for auth persistence (DEV ONLY — production uses D1)'
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
key: 'VIBES_AUTH_RESEND_API_KEY',
|
|
82
|
+
category: 'vibes-auth',
|
|
83
|
+
source: 'local-env',
|
|
84
|
+
aliases: ['RESEND_API_KEY'],
|
|
85
|
+
required: false,
|
|
86
|
+
description: 'Resend API key for auth email delivery'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
key: 'VIBES_AUTH_TWILIO_ACCOUNT_SID',
|
|
90
|
+
category: 'vibes-auth',
|
|
91
|
+
source: 'local-env',
|
|
92
|
+
required: false,
|
|
93
|
+
description: 'Twilio account SID for phone OTP delivery'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: 'VIBES_AUTH_TWILIO_AUTH_TOKEN',
|
|
97
|
+
category: 'vibes-auth',
|
|
98
|
+
source: 'local-env',
|
|
99
|
+
required: false,
|
|
100
|
+
description: 'Twilio auth token for phone OTP delivery'
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
key: 'VIBES_AUTH_GITHUB_CLIENT_ID',
|
|
104
|
+
category: 'vibes-auth',
|
|
105
|
+
source: 'local-env',
|
|
106
|
+
required: false,
|
|
107
|
+
description: 'GitHub OAuth client ID'
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: 'VIBES_AUTH_GITHUB_CLIENT_SECRET',
|
|
111
|
+
category: 'vibes-auth',
|
|
112
|
+
source: 'local-env',
|
|
113
|
+
required: false,
|
|
114
|
+
description: 'GitHub OAuth client secret'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
key: 'VIBES_AUTH_GOOGLE_CLIENT_ID',
|
|
118
|
+
category: 'vibes-auth',
|
|
119
|
+
source: 'local-env',
|
|
120
|
+
required: false,
|
|
121
|
+
description: 'Google OAuth client ID'
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
key: 'VIBES_AUTH_GOOGLE_CLIENT_SECRET',
|
|
125
|
+
category: 'vibes-auth',
|
|
126
|
+
source: 'local-env',
|
|
127
|
+
required: false,
|
|
128
|
+
description: 'Google OAuth client secret'
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
key: 'VIBES_AUTH_DISCORD_CLIENT_ID',
|
|
132
|
+
category: 'vibes-auth',
|
|
133
|
+
source: 'local-env',
|
|
134
|
+
required: false,
|
|
135
|
+
description: 'Discord OAuth client ID'
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
key: 'VIBES_AUTH_DISCORD_CLIENT_SECRET',
|
|
139
|
+
category: 'vibes-auth',
|
|
140
|
+
source: 'local-env',
|
|
141
|
+
required: false,
|
|
142
|
+
description: 'Discord OAuth client secret'
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
key: 'VIBES_AUTH_MICROSOFT_CLIENT_ID',
|
|
146
|
+
category: 'vibes-auth',
|
|
147
|
+
source: 'local-env',
|
|
148
|
+
required: false,
|
|
149
|
+
description: 'Microsoft (Azure AD) OAuth client ID'
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
key: 'VIBES_AUTH_MICROSOFT_CLIENT_SECRET',
|
|
153
|
+
category: 'vibes-auth',
|
|
154
|
+
source: 'local-env',
|
|
155
|
+
required: false,
|
|
156
|
+
description: 'Microsoft (Azure AD) OAuth client secret'
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
// --- Internal cross-app bearer tokens (account-web, ai-web) ------------------
|
|
160
|
+
{
|
|
161
|
+
key: 'VIBES_AUTH_INTERNAL_TOKEN',
|
|
162
|
+
category: 'vibes-internal',
|
|
163
|
+
source: 'local-env',
|
|
164
|
+
required: true,
|
|
165
|
+
description: 'Bearer token for internal/admin auth API calls'
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
key: 'VIBES_INTERNAL_SERVICE_TOKEN',
|
|
169
|
+
category: 'vibes-internal',
|
|
170
|
+
source: 'manual',
|
|
171
|
+
required: true,
|
|
172
|
+
description: 'Shared internal bearer token for platform/account internal RPCs'
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
key: 'VIBES_PLATFORM_INTERNAL_TOKEN',
|
|
176
|
+
category: 'vibes-internal',
|
|
177
|
+
source: 'manual',
|
|
178
|
+
required: false,
|
|
179
|
+
description: 'Platform-specific internal bearer token; falls back to VIBES_INTERNAL_SERVICE_TOKEN'
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
key: 'VIBES_EMAIL_INGRESS_TOKEN',
|
|
183
|
+
category: 'vibes-internal',
|
|
184
|
+
source: 'manual',
|
|
185
|
+
required: false,
|
|
186
|
+
description: 'Bearer token for inbound email webhooks (auth-web /api/email)'
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
// --- Billing (account-web) ---------------------------------------------------
|
|
190
|
+
// `.env.production` stores Stripe under a `VIBES_ACCOUNT_STRIPE_*` prefix;
|
|
191
|
+
// `.env.local` uses the canonical names directly. Either source resolves.
|
|
192
|
+
{
|
|
193
|
+
key: 'STRIPE_SECRET_KEY',
|
|
194
|
+
category: 'provider-billing',
|
|
195
|
+
source: 'local-env',
|
|
196
|
+
aliases: ['VIBES_ACCOUNT_STRIPE_SECRET_KEY'],
|
|
197
|
+
required: false,
|
|
198
|
+
description: 'Stripe secret key for billing sync and checkout'
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
key: 'STRIPE_WEBHOOK_SECRET',
|
|
202
|
+
category: 'provider-billing',
|
|
203
|
+
source: 'local-env',
|
|
204
|
+
required: false,
|
|
205
|
+
description: 'Stripe webhook signing secret for /api/webhooks/stripe'
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
key: 'STRIPE_PUB_KEY',
|
|
209
|
+
category: 'provider-billing',
|
|
210
|
+
source: 'local-env',
|
|
211
|
+
aliases: ['PUBLIC_STRIPE_KEY', 'VIBES_ACCOUNT_STRIPE_PUB_KEY'],
|
|
212
|
+
required: false,
|
|
213
|
+
description: 'Stripe publishable key (pk_live_*/pk_test_*); safe to expose to clients but tracked here so live/test mode stays aligned with STRIPE_SECRET_KEY'
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
key: 'STRIPE_RESTRICTED_KEY',
|
|
217
|
+
category: 'provider-billing',
|
|
218
|
+
source: 'local-env',
|
|
219
|
+
aliases: ['VIBES_ACCOUNT_STRIPE_RESTRICTED_KEY'],
|
|
220
|
+
required: false,
|
|
221
|
+
description: 'Stripe restricted live key (rk_live_*) for narrow-scope ops/CI usage; not consumed at runtime — runtime uses STRIPE_SECRET_KEY'
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
key: 'CF_BILLING_SECRET',
|
|
225
|
+
category: 'vibes-internal',
|
|
226
|
+
source: 'manual',
|
|
227
|
+
required: false,
|
|
228
|
+
description: 'Cloudflare-side billing webhook secret'
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
key: 'RESEND_API_KEY',
|
|
232
|
+
category: 'provider-other',
|
|
233
|
+
source: 'manual',
|
|
234
|
+
required: false,
|
|
235
|
+
description: 'Resend API key used by account-web to send invoice receipt emails'
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
// --- LLM / voice / search providers (ai-web, ai-web) ----------------------
|
|
239
|
+
{
|
|
240
|
+
key: 'OPENAI_API_KEY',
|
|
241
|
+
category: 'provider-llm',
|
|
242
|
+
source: 'manual',
|
|
243
|
+
required: false,
|
|
244
|
+
description: 'OpenAI provider key (ai-web)'
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
key: 'ANTHROPIC_API_KEY',
|
|
248
|
+
category: 'provider-llm',
|
|
249
|
+
source: 'manual',
|
|
250
|
+
required: false,
|
|
251
|
+
description: 'Anthropic provider key (ai-web)'
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
key: 'GOOGLE_API_KEY',
|
|
255
|
+
category: 'provider-llm',
|
|
256
|
+
source: 'manual',
|
|
257
|
+
required: false,
|
|
258
|
+
description: 'Google provider key (ai-web)'
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
key: 'GEMINI_API_KEY',
|
|
262
|
+
category: 'provider-llm',
|
|
263
|
+
source: 'manual',
|
|
264
|
+
required: false,
|
|
265
|
+
description: 'Gemini-named provider key alias (ai-web)'
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
key: 'DEEPGRAM_API_KEY',
|
|
269
|
+
category: 'provider-voice',
|
|
270
|
+
source: 'manual',
|
|
271
|
+
required: false,
|
|
272
|
+
description: 'Deepgram transcription provider key (ai-web)'
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
key: 'ELEVENLABS_API_KEY',
|
|
276
|
+
category: 'provider-voice',
|
|
277
|
+
source: 'manual',
|
|
278
|
+
required: false,
|
|
279
|
+
description: 'ElevenLabs TTS provider key (ai-web)'
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
key: 'FIRECRAWL_API_KEY',
|
|
283
|
+
category: 'provider-search',
|
|
284
|
+
source: 'manual',
|
|
285
|
+
required: false,
|
|
286
|
+
description: 'Firecrawl crawl/scrape provider key (ai-web)'
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
key: 'VIBES_API_TOKEN',
|
|
290
|
+
category: 'vibes-internal',
|
|
291
|
+
source: 'manual',
|
|
292
|
+
required: false,
|
|
293
|
+
description: 'Tools-web internal API token'
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
key: 'VIBES_TOOL_REGISTRY_TOKEN',
|
|
297
|
+
category: 'vibes-internal',
|
|
298
|
+
source: 'manual',
|
|
299
|
+
required: false,
|
|
300
|
+
description: 'Tools-web tool-registry access token'
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
// --- Other provider creds (referenced by deployment configs but not in
|
|
304
|
+
// a Pages app's secrets list yet — included so they round-trip if
|
|
305
|
+
// they end up in `.env.local`) -----------------------------------------
|
|
306
|
+
{
|
|
307
|
+
key: 'DIGITALOCEAN_API_TOKEN',
|
|
308
|
+
category: 'provider-other',
|
|
309
|
+
source: 'local-env',
|
|
310
|
+
required: false,
|
|
311
|
+
description: 'DigitalOcean API token for DOKS / DO Spaces tooling'
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
key: 'NPM_TOKEN',
|
|
315
|
+
category: 'provider-other',
|
|
316
|
+
source: 'manual',
|
|
317
|
+
required: false,
|
|
318
|
+
description: 'npm publish token used by `vibes infra npm publish`'
|
|
319
|
+
}
|
|
320
|
+
]
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
export const canonicalImportManifest: SecretsImportManifest = manifest;
|
|
324
|
+
export default manifest;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secrets Import Manifest Schema
|
|
3
|
+
*
|
|
4
|
+
* Catalogs the secrets the platform expects to receive from local root env
|
|
5
|
+
* files at bootstrap time. Carries no values — only key identity, source
|
|
6
|
+
* preference, and intent. The manifest is the contract a `vibes secrets
|
|
7
|
+
* import` command (phase 5) reads against.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as z from 'zod/v4';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Where a secret value is expected to originate from when running
|
|
14
|
+
* `vibes secrets import`. Sources with a `path` are repo-relative .env-shaped
|
|
15
|
+
* files; they are read-only inputs and never committed. Sources without a
|
|
16
|
+
* `path` (e.g. the canonical `manual` source) describe entries that are not
|
|
17
|
+
* importable from disk and must be set through other means
|
|
18
|
+
* (`vibes secrets set`, generated tokens, Cloudflare dashboard, etc.).
|
|
19
|
+
*/
|
|
20
|
+
export const SecretSourceSchema = z.object({
|
|
21
|
+
/** Repo-relative path to the .env file. Omit for non-importable sources. */
|
|
22
|
+
path: z.string().min(1).optional(),
|
|
23
|
+
/** Why this source owns this category of secrets (Vibes internals, providers, etc.) */
|
|
24
|
+
purpose: z.string().min(1)
|
|
25
|
+
});
|
|
26
|
+
export type SecretSource = z.infer<typeof SecretSourceSchema>;
|
|
27
|
+
|
|
28
|
+
export const SecretCategorySchema = z.enum([
|
|
29
|
+
'vibes-internal',
|
|
30
|
+
'vibes-auth',
|
|
31
|
+
'cloudflare',
|
|
32
|
+
'provider-llm',
|
|
33
|
+
'provider-voice',
|
|
34
|
+
'provider-search',
|
|
35
|
+
'provider-billing',
|
|
36
|
+
'provider-other'
|
|
37
|
+
]);
|
|
38
|
+
export type SecretCategory = z.infer<typeof SecretCategorySchema>;
|
|
39
|
+
|
|
40
|
+
export const SecretManifestEntrySchema = z.object({
|
|
41
|
+
/** Canonical key in Cloudflare Secrets Store. Matches env var name unless renamed. */
|
|
42
|
+
key: z.string().regex(/^[_A-Z0-9]+$/),
|
|
43
|
+
/** Category this secret belongs to (drives source-file routing) */
|
|
44
|
+
category: SecretCategorySchema,
|
|
45
|
+
/** Preferred source file id (must exist in `sources`) */
|
|
46
|
+
source: z.string().min(1),
|
|
47
|
+
/** Alternate names this secret may appear under in the source file */
|
|
48
|
+
aliases: z.array(z.string().regex(/^[_A-Z0-9]+$/)).default([]),
|
|
49
|
+
/** Whether the secret is required for a production push */
|
|
50
|
+
required: z.boolean().default(true),
|
|
51
|
+
/** Human-readable description of what this secret unlocks */
|
|
52
|
+
description: z.string().min(1)
|
|
53
|
+
});
|
|
54
|
+
export type SecretManifestEntry = z.infer<typeof SecretManifestEntrySchema>;
|
|
55
|
+
|
|
56
|
+
export const SecretsImportManifestSchema = z.object({
|
|
57
|
+
version: z.literal(1),
|
|
58
|
+
/** Map of source id → file path + purpose */
|
|
59
|
+
sources: z.record(z.string().min(1), SecretSourceSchema),
|
|
60
|
+
/** Catalog of expected secrets, keyed by canonical name */
|
|
61
|
+
secrets: z.array(SecretManifestEntrySchema)
|
|
62
|
+
});
|
|
63
|
+
export type SecretsImportManifest = z.infer<typeof SecretsImportManifestSchema>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export {
|
|
2
|
+
SecretsImportManifestSchema,
|
|
3
|
+
SecretManifestEntrySchema,
|
|
4
|
+
SecretSourceSchema,
|
|
5
|
+
SecretCategorySchema,
|
|
6
|
+
type SecretsImportManifest,
|
|
7
|
+
type SecretManifestEntry,
|
|
8
|
+
type SecretSource,
|
|
9
|
+
type SecretCategory
|
|
10
|
+
} from './import-manifest.schema';
|
|
11
|
+
|
|
12
|
+
export { canonicalImportManifest } from './canonical';
|