vaulter 1.0.33 → 1.0.35

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 CHANGED
@@ -312,47 +312,164 @@ Vaulter separates **local development** from **deployment** configurations:
312
312
 
313
313
  ## CI/CD
314
314
 
315
- ### GitHub Actions (Recommended)
315
+ ### GitHub Action (Recommended)
316
316
 
317
- Use `vaulter run` to execute commands with auto-loaded environment variables:
317
+ Use the official Vaulter GitHub Action for seamless CI/CD integration:
318
318
 
319
319
  ```yaml
320
- name: Build & Deploy
321
- on:
322
- push:
323
- branches: [main]
324
-
325
- jobs:
326
- build:
327
- runs-on: ubuntu-latest
328
- steps:
329
- - uses: actions/checkout@v4
330
- - uses: pnpm/action-setup@v4
331
-
332
- - name: Pull secrets from backend
333
- env:
334
- VAULTER_KEY: ${{ secrets.VAULTER_KEY }}
335
- AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
336
- AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
337
- run: npx vaulter sync pull -e prd
338
-
339
- - name: Build with env vars
340
- run: npx vaulter run -e prd -- pnpm build
341
-
342
- deploy:
343
- needs: build
344
- runs-on: ubuntu-latest
345
- steps:
346
- - uses: actions/checkout@v4
347
- - name: Deploy secrets to K8s
348
- env:
349
- VAULTER_KEY: ${{ secrets.VAULTER_KEY }}
350
- AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
351
- AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
352
- run: npx vaulter export k8s-secret -e prd | kubectl apply -f -
353
- ```
354
-
355
- **Auto-detection in CI:** When `CI=true` or `GITHUB_ACTIONS` is set, vaulter automatically loads from `.vaulter/deploy/` instead of `.vaulter/local/`.
320
+ - uses: forattini-dev/vaulter@v1
321
+ id: secrets
322
+ with:
323
+ backend: s3://my-bucket/secrets
324
+ project: my-app
325
+ environment: prd
326
+ outputs: env,k8s-secret
327
+ env:
328
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
329
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
330
+ VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
331
+ ```
332
+
333
+ #### Output Formats
334
+
335
+ | Output | File | Use Case |
336
+ |:-------|:-----|:---------|
337
+ | `env` | `.env` | Docker, Node.js |
338
+ | `json` | `vaulter-vars.json` | Custom scripts |
339
+ | `k8s-secret` | `k8s-secret.yaml` | `kubectl apply` |
340
+ | `k8s-configmap` | `k8s-configmap.yaml` | `kubectl apply` |
341
+ | `helm-values` | `helm-values.yaml` | `helmfile`, `helm` |
342
+ | `tfvars` | `terraform.auto.tfvars` | `terraform`, `terragrunt` |
343
+ | `shell` | `vaulter-env.sh` | `source` in scripts |
344
+
345
+ #### Full Examples
346
+
347
+ **kubectl:**
348
+ ```yaml
349
+ - uses: forattini-dev/vaulter@v1
350
+ with:
351
+ backend: ${{ secrets.VAULTER_BACKEND }}
352
+ project: my-app
353
+ environment: prd
354
+ outputs: k8s-secret,k8s-configmap
355
+ k8s-namespace: my-namespace
356
+ env:
357
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
358
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
359
+ VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
360
+
361
+ - run: |
362
+ kubectl apply -f k8s-secret.yaml
363
+ kubectl apply -f k8s-configmap.yaml
364
+ ```
365
+
366
+ **Helmfile:**
367
+ ```yaml
368
+ - uses: forattini-dev/vaulter@v1
369
+ with:
370
+ backend: ${{ secrets.VAULTER_BACKEND }}
371
+ project: my-app
372
+ environment: prd
373
+ outputs: helm-values
374
+ helm-values-path: ./helm/secrets.yaml
375
+ env:
376
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
377
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
378
+ VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
379
+
380
+ - run: helmfile -e prd apply
381
+ ```
382
+
383
+ **Terraform/Terragrunt:**
384
+ ```yaml
385
+ - uses: forattini-dev/vaulter@v1
386
+ with:
387
+ backend: ${{ secrets.VAULTER_BACKEND }}
388
+ project: infra
389
+ environment: prd
390
+ outputs: tfvars
391
+ # .auto.tfvars is loaded automatically by Terraform!
392
+ tfvars-path: ./secrets.auto.tfvars
393
+ env:
394
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
395
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
396
+ VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
397
+
398
+ - run: terragrunt apply -auto-approve
399
+ ```
400
+
401
+ **Docker Build:**
402
+ ```yaml
403
+ - uses: forattini-dev/vaulter@v1
404
+ with:
405
+ backend: ${{ secrets.VAULTER_BACKEND }}
406
+ project: my-app
407
+ environment: prd
408
+ outputs: env
409
+ env-path: .env.production
410
+ env:
411
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
412
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
413
+ VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
414
+
415
+ - run: docker build --secret id=env,src=.env.production -t app .
416
+ ```
417
+
418
+ **Export to GITHUB_ENV:**
419
+ ```yaml
420
+ - uses: forattini-dev/vaulter@v1
421
+ with:
422
+ backend: ${{ secrets.VAULTER_BACKEND }}
423
+ project: my-app
424
+ environment: prd
425
+ export-to-env: true # Makes vars available in subsequent steps
426
+ env:
427
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
428
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
429
+ VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
430
+
431
+ - run: echo "Database is $DATABASE_URL" # Available!
432
+ ```
433
+
434
+ #### Action Inputs
435
+
436
+ | Input | Required | Default | Description |
437
+ |:------|:--------:|:--------|:------------|
438
+ | `backend` | ✓ | - | S3 connection string |
439
+ | `project` | ✓ | - | Project name |
440
+ | `environment` | ✓ | - | Environment (dev/stg/prd) |
441
+ | `service` | | - | Service (monorepo) |
442
+ | `outputs` | | `env` | Comma-separated outputs |
443
+ | `k8s-namespace` | | `default` | K8s namespace |
444
+ | `export-to-env` | | `false` | Export to GITHUB_ENV |
445
+ | `mask-values` | | `true` | Mask secrets in logs |
446
+
447
+ #### Action Outputs
448
+
449
+ | Output | Description |
450
+ |:-------|:------------|
451
+ | `env-file` | Path to .env file |
452
+ | `k8s-secret-file` | Path to K8s Secret YAML |
453
+ | `k8s-configmap-file` | Path to K8s ConfigMap YAML |
454
+ | `helm-values-file` | Path to Helm values file |
455
+ | `tfvars-file` | Path to .tfvars file |
456
+ | `vars-count` | Number of variables |
457
+ | `vars-json` | JSON array of variable names |
458
+
459
+ ### CLI in CI/CD
460
+
461
+ You can also use the CLI directly:
462
+
463
+ ```yaml
464
+ - name: Pull and build
465
+ env:
466
+ VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
467
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
468
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
469
+ run: |
470
+ npx vaulter sync pull -e prd
471
+ npx vaulter run -e prd -- pnpm build
472
+ ```
356
473
 
357
474
  ### Other Platforms
358
475
 
@@ -417,6 +534,112 @@ vaulter export shell -e dev -s api --no-shared
417
534
 
418
535
  ---
419
536
 
537
+ ## Output Targets (Multi-Framework)
538
+
539
+ **One config → multiple `.env` files.** Works with any framework: Next.js, NestJS, Express, NX, Turborepo, etc.
540
+
541
+ ### The Problem
542
+
543
+ Different apps need different variables in different places:
544
+
545
+ ```
546
+ apps/
547
+ ├── web/ # Next.js needs .env.local with NEXT_PUBLIC_*
548
+ ├── api/ # NestJS needs .env with DATABASE_*, JWT_*
549
+ └── admin/ # Needs everything
550
+ ```
551
+
552
+ ### The Solution
553
+
554
+ Define outputs once, pull everywhere:
555
+
556
+ ```yaml
557
+ # .vaulter/config.yaml
558
+ outputs:
559
+ web:
560
+ path: apps/web
561
+ filename: .env.local
562
+ include: [NEXT_PUBLIC_*] # Only public vars
563
+
564
+ api:
565
+ path: apps/api
566
+ include: [DATABASE_*, JWT_*] # Only backend vars
567
+ exclude: [*_DEV] # No dev-only vars
568
+
569
+ admin: apps/admin # Shorthand: all vars
570
+
571
+ # Shared across all outputs (inherited automatically)
572
+ shared:
573
+ include: [NODE_ENV, LOG_LEVEL, SENTRY_*]
574
+ ```
575
+
576
+ ### Pull to All Outputs
577
+
578
+ ```bash
579
+ # Pull to all outputs at once
580
+ vaulter sync pull --all
581
+
582
+ # Result:
583
+ # ✓ web: apps/web/.env.local (5 vars)
584
+ # ✓ api: apps/api/.env (12 vars)
585
+ # ✓ admin: apps/admin/.env (25 vars)
586
+ ```
587
+
588
+ ### Pull to Specific Output
589
+
590
+ ```bash
591
+ # Pull only web
592
+ vaulter sync pull --output web
593
+
594
+ # Preview without writing
595
+ vaulter sync pull --all --dry-run
596
+ ```
597
+
598
+ ### How It Works
599
+
600
+ ```
601
+ ┌─────────────────────────────────────────────────────────┐
602
+ │ Backend (S3) │
603
+ │ DATABASE_URL, JWT_SECRET, NEXT_PUBLIC_API, LOG_LEVEL │
604
+ └────────────────────────┬────────────────────────────────┘
605
+
606
+ vaulter sync pull --all
607
+
608
+ ┌───────────────┼───────────────┐
609
+ ▼ ▼ ▼
610
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
611
+ │ web │ │ api │ │ admin │
612
+ │ .env.local│ │ .env │ │ .env │
613
+ │ │ │ │ │ │
614
+ │ LOG_LEVEL│ │ LOG_LEVEL│ │ LOG_LEVEL│ ← shared (inherited)
615
+ │ NEXT_* │ │ DATABASE_│ │ ALL VARS │ ← filtered by include/exclude
616
+ └──────────┘ │ JWT_* │ └──────────┘
617
+ └──────────┘
618
+ ```
619
+
620
+ ### Pattern Syntax
621
+
622
+ | Pattern | Matches |
623
+ |:--------|:--------|
624
+ | `NEXT_PUBLIC_*` | `NEXT_PUBLIC_API_URL`, `NEXT_PUBLIC_GA_ID` |
625
+ | `*_SECRET` | `JWT_SECRET`, `API_SECRET` |
626
+ | `DATABASE_*` | `DATABASE_URL`, `DATABASE_HOST` |
627
+ | `*_URL` | `API_URL`, `DATABASE_URL`, `REDIS_URL` |
628
+
629
+ ### Inheritance
630
+
631
+ By default, `shared.include` vars are added to ALL outputs. Override with `inherit: false`:
632
+
633
+ ```yaml
634
+ outputs:
635
+ isolated-app:
636
+ path: apps/isolated
637
+ inherit: false # No shared vars
638
+ include: [ISOLATED_*]
639
+ ```
640
+
641
+ ---
642
+
420
643
  ## API Usage
421
644
 
422
645
  ```typescript
package/action.yml ADDED
@@ -0,0 +1,116 @@
1
+ name: 'Vaulter - Pull Secrets'
2
+ description: 'Pull environment variables from Vaulter backend and generate outputs for kubectl, helm, terraform, and more'
3
+ author: 'Forattini'
4
+ branding:
5
+ icon: 'lock'
6
+ color: 'purple'
7
+
8
+ inputs:
9
+ # ─── Connection ───
10
+ backend:
11
+ description: 'Connection string (s3://bucket, file://path, memory://). Can also use VAULTER_BACKEND env var.'
12
+ required: false
13
+ passphrase:
14
+ description: 'Encryption passphrase for symmetric mode. Can also use VAULTER_PASSPHRASE env var.'
15
+ required: false
16
+
17
+ # ─── Filters ───
18
+ project:
19
+ description: 'Project name'
20
+ required: true
21
+ environment:
22
+ description: 'Environment (dev/stg/prd or custom)'
23
+ required: true
24
+ service:
25
+ description: 'Service name for monorepo setups'
26
+ required: false
27
+
28
+ # ─── Outputs Selection ───
29
+ outputs:
30
+ description: 'Comma-separated list of outputs to generate: env,json,k8s-secret,k8s-configmap,helm-values,tfvars,shell'
31
+ default: 'env'
32
+
33
+ # ─── Output Paths ───
34
+ env-path:
35
+ description: 'Path for .env file output'
36
+ default: '.env'
37
+ json-path:
38
+ description: 'Path for JSON output'
39
+ default: 'vaulter-vars.json'
40
+ k8s-secret-path:
41
+ description: 'Path for Kubernetes Secret YAML'
42
+ default: 'k8s-secret.yaml'
43
+ k8s-configmap-path:
44
+ description: 'Path for Kubernetes ConfigMap YAML'
45
+ default: 'k8s-configmap.yaml'
46
+ helm-values-path:
47
+ description: 'Path for Helm values.yaml'
48
+ default: 'helm-values.yaml'
49
+ tfvars-path:
50
+ description: 'Path for Terraform .tfvars file'
51
+ default: 'terraform.auto.tfvars'
52
+ shell-path:
53
+ description: 'Path for shell export script'
54
+ default: 'vaulter-env.sh'
55
+
56
+ # ─── K8s Options ───
57
+ k8s-secret-name:
58
+ description: 'Name for Kubernetes Secret resource'
59
+ required: false
60
+ k8s-configmap-name:
61
+ description: 'Name for Kubernetes ConfigMap resource'
62
+ required: false
63
+ k8s-namespace:
64
+ description: 'Kubernetes namespace'
65
+ default: 'default'
66
+
67
+ # ─── Encryption Mode ───
68
+ encryption-mode:
69
+ description: 'Encryption mode: symmetric or asymmetric'
70
+ default: 'symmetric'
71
+ public-key:
72
+ description: 'Public key PEM content (asymmetric mode)'
73
+ required: false
74
+ private-key:
75
+ description: 'Private key PEM content (asymmetric mode)'
76
+ required: false
77
+ asymmetric-algorithm:
78
+ description: 'Algorithm for asymmetric mode: rsa-4096, rsa-2048, ec-p256, ec-p384'
79
+ default: 'rsa-4096'
80
+
81
+ # ─── Shared Vars ───
82
+ include-shared:
83
+ description: 'Include shared variables when service is specified'
84
+ default: 'true'
85
+
86
+ # ─── Export to GitHub Env ───
87
+ export-to-env:
88
+ description: 'Export variables to GITHUB_ENV for subsequent steps'
89
+ default: 'false'
90
+ mask-values:
91
+ description: 'Mask secret values in logs'
92
+ default: 'true'
93
+
94
+ outputs:
95
+ env-file:
96
+ description: 'Path to generated .env file'
97
+ json-file:
98
+ description: 'Path to generated JSON file'
99
+ k8s-secret-file:
100
+ description: 'Path to generated Kubernetes Secret YAML'
101
+ k8s-configmap-file:
102
+ description: 'Path to generated Kubernetes ConfigMap YAML'
103
+ helm-values-file:
104
+ description: 'Path to generated Helm values file'
105
+ tfvars-file:
106
+ description: 'Path to generated Terraform .tfvars file'
107
+ shell-file:
108
+ description: 'Path to generated shell export script'
109
+ vars-count:
110
+ description: 'Number of variables exported'
111
+ vars-json:
112
+ description: 'JSON string with all variable names (not values)'
113
+
114
+ runs:
115
+ using: 'node20'
116
+ main: 'dist/action/index.cjs'
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Vaulter GitHub Action - Output Format Generators
3
+ *
4
+ * Generates output files in various formats for different IaC tools:
5
+ * - env: Standard .env file
6
+ * - json: JSON key-value pairs
7
+ * - k8s-secret: Kubernetes Secret YAML
8
+ * - k8s-configmap: Kubernetes ConfigMap YAML
9
+ * - helm-values: Helm values.yaml
10
+ * - tfvars: Terraform .tfvars
11
+ * - shell: Shell export script
12
+ */
13
+ /**
14
+ * Generate .env file content
15
+ */
16
+ export declare function generateEnvFile(vars: Record<string, string>): string;
17
+ /**
18
+ * Generate JSON file content
19
+ */
20
+ export declare function generateJsonFile(vars: Record<string, string>): string;
21
+ /**
22
+ * Generate Kubernetes Secret YAML
23
+ */
24
+ export declare function generateK8sSecret(vars: Record<string, string>, options: {
25
+ name: string;
26
+ namespace: string;
27
+ environment: string;
28
+ }): string;
29
+ /**
30
+ * Generate Kubernetes ConfigMap YAML
31
+ */
32
+ export declare function generateK8sConfigMap(vars: Record<string, string>, options: {
33
+ name: string;
34
+ namespace: string;
35
+ environment: string;
36
+ }): string;
37
+ /**
38
+ * Generate Helm values.yaml
39
+ */
40
+ export declare function generateHelmValues(vars: Record<string, string>, options: {
41
+ project: string;
42
+ environment: string;
43
+ service?: string;
44
+ }): string;
45
+ /**
46
+ * Generate Terraform .tfvars
47
+ */
48
+ export declare function generateTfVars(vars: Record<string, string>, options: {
49
+ project: string;
50
+ environment: string;
51
+ service?: string;
52
+ }): string;
53
+ /**
54
+ * Generate shell export script
55
+ */
56
+ export declare function generateShellExport(vars: Record<string, string>): string;
57
+ //# sourceMappingURL=formats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/action/formats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAyGH;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAYpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAErE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,GACA,MAAM,CAsBR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,GACA,MAAM,CAqBR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GACA,MAAM,CA4BR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GACA,MAAM,CA6BR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAcxE"}