@aifabrix/builder 2.59.0 → 2.61.2
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 +14 -11
- package/docs/README.md +80 -0
- package/docs/builder-help/evidence-patterns.json +155 -0
- package/docs/builder-help/golden-examples/crm-company.json +30 -0
- package/docs/builder-help/golden-examples/crm-deal.json +29 -0
- package/docs/builder-help/golden-examples/document-storage-keyed-get.json +85 -0
- package/docs/builder-help/golden-examples/document-storage.json +30 -0
- package/docs/builder-help/golden-examples/meeting-transcript.json +29 -0
- package/docs/builder-help/golden-examples/repository-template.json +29 -0
- package/docs/builder-help/golden-examples/service-ticket.json +29 -0
- package/docs/builder-help/platform-roles.json +98 -0
- package/docs/builder-help/resource-type-catalog.json +402 -0
- package/lib/agent-kit/git-identity.js +180 -0
- package/lib/agent-kit/setup.js +3 -0
- package/lib/agent-kit/start.js +45 -1
- package/lib/api/configuration.api.js +131 -0
- package/lib/api/role-assistant-test-job.api.js +60 -0
- package/lib/api/system-secrets.api.js +72 -0
- package/lib/api/work-search.api.js +13 -6
- package/lib/app/deploy.js +8 -1
- package/lib/app/run-docker-fallback.js +6 -1
- package/lib/app/run-helpers.js +2 -1
- package/lib/app/run-parameter-sync.js +142 -0
- package/lib/app/show-display.js +1 -0
- package/lib/app/show-online.js +15 -0
- package/lib/build/docker-build-args.js +5 -2
- package/lib/build/index.js +3 -2
- package/lib/build/standard-docker-build.js +6 -3
- package/lib/cli/setup-app.js +19 -1
- package/lib/cli/setup-environment.js +156 -0
- package/lib/cli/setup-utility.js +24 -1
- package/lib/commands/datasource-capability-upsert-cli.js +112 -0
- package/lib/commands/datasource-capability.js +4 -2
- package/lib/commands/env-secret-context.js +113 -0
- package/lib/commands/env-secret-list.js +200 -0
- package/lib/commands/env-secret-push-confirm.js +54 -0
- package/lib/commands/env-secret-push-run.js +227 -0
- package/lib/commands/env-secret-push.js +168 -0
- package/lib/commands/repair-datasource-apply.js +2 -0
- package/lib/commands/repair-datasource-keyed-document.js +122 -0
- package/lib/commands/repair-datasource-run.js +1 -0
- package/lib/commands/role-assistant.js +7 -0
- package/lib/commands/setup-modes.js +1 -8
- package/lib/commands/setup-prompts.js +2 -180
- package/lib/commands/verify-operations-skip-e2e.js +25 -1
- package/lib/commands/verify-operations-steps.js +13 -1
- package/lib/commands/wizard-config-normalizer.js +7 -4
- package/lib/commands/wizard-core.js +5 -157
- package/lib/commands/wizard-file-saving.js +163 -0
- package/lib/core/env-platform-expand.js +97 -0
- package/lib/core/secrets-env-content.js +42 -4
- package/lib/core/secrets-env-write.js +10 -3
- package/lib/core/secrets-load.js +4 -2
- package/lib/datasource/binary-documents-validator.js +190 -0
- package/lib/datasource/capability/run-capability-upsert.js +202 -0
- package/lib/datasource/capability/upsert-ingredients.js +291 -0
- package/lib/datasource/capability/upsert-operations.js +138 -0
- package/lib/datasource/capability/upsert-test-scaffold.js +189 -0
- package/lib/datasource/validate.js +12 -5
- package/lib/deployment/installation/azure-infra-stage.js +3 -1
- package/lib/deployment/installation/infra-catalog.js +2 -5
- package/lib/generator/builders.js +17 -0
- package/lib/generator/helpers.js +23 -2
- package/lib/generator/index.js +13 -6
- package/lib/lifecycle/product-model.js +4 -3
- package/lib/lifecycle/report-display.js +3 -2
- package/lib/parameters/infra-parameter-catalog.js +1 -1
- package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +1 -1
- package/lib/programmatic/builder-help-governance.js +1 -1
- package/lib/programmatic/builder-help.js +1 -1
- package/lib/role-assistant/test-cases-search.js +3 -0
- package/lib/role-assistant/test-job-runner.js +125 -0
- package/lib/role-assistant/test-runner-search.js +44 -2
- package/lib/role-assistant/test-runner-workhub-answers.js +4 -1
- package/lib/role-assistant/test-runner-workhub-missing-fields.js +42 -0
- package/lib/role-assistant/test-runner-workhub-wait-stop.js +94 -0
- package/lib/role-assistant/test-runner-workhub.js +28 -19
- package/lib/schema/application-schema.json +205 -2
- package/lib/schema/external-datasource.schema.json +23 -3
- package/lib/schema/infra-parameter.schema.json +139 -33
- package/lib/schema/infra.parameter.yaml +416 -66
- package/lib/schema/infrastructure-schema.json +10 -35
- package/lib/utils/compose-generate-docker-compose.js +16 -9
- package/lib/utils/datasource-binary-evidence.js +92 -0
- package/lib/utils/datasource-test-run-capability-scope.js +44 -1
- package/lib/utils/datasource-test-run-debug-display.js +2 -0
- package/lib/utils/datasource-test-run-display.js +8 -2
- package/lib/utils/datasource-test-run-issue-guidance.js +176 -0
- package/lib/utils/datasource-test-run-tty-log.js +2 -0
- package/lib/utils/docker-build.js +29 -8
- package/lib/utils/docker-manifest-public-port.js +36 -0
- package/lib/utils/env-copy.js +11 -10
- package/lib/utils/external-system-system-test-tty.js +3 -2
- package/lib/utils/image-tags.js +2 -2
- package/lib/utils/platform-kv-ref.js +1 -1
- package/lib/utils/platform-resolution.js +226 -0
- package/lib/utils/prepare-local-data-mount.js +58 -0
- package/lib/utils/resolve-docker-image-ref.js +8 -3
- package/lib/utils/secrets-helpers.js +0 -1
- package/lib/utils/system-secret-mapping.js +125 -0
- package/lib/utils/test-log-writer.js +2 -1
- package/lib/validation/external-manifest-validator.js +5 -0
- package/lib/validation/openapi-contract-surface-validator.js +3 -1
- package/lib/validation/validate-external-file.js +5 -1
- package/package.json +5 -4
- package/templates/README.md +2 -1
- package/templates/agent-kit/agent-kit.yaml +4 -1
- package/templates/agent-kit/instructions/AGENTKIT.md +1 -1
- package/templates/agent-kit/instructions/root.AGENTS.md +2 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +35 -2
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +15 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/delivery-verdict.js +176 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +6 -2
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +28 -2
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +22 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +28 -1
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/testing-playbook.md +117 -0
- package/templates/agent-kit/skills/shared/feedback.md +31 -0
- package/templates/agent-kit/skills/shared/hosts.md +13 -3
- package/templates/agent-kit/skills/shared/interaction.md +83 -0
- package/templates/agent-kit/skills/shared/status.md +76 -0
- package/templates/agent-kit/workspace/BUILDER_IMPROVEMENT_FINDINGS.md +27 -0
- package/templates/applications/builder-api/application.yaml +1 -1
- package/templates/applications/builder-api/env.template +5 -1
- package/templates/applications/dataplane/application.yaml +30 -2
- package/templates/applications/dataplane/env.template +36 -5
- package/templates/applications/keycloak/application.yaml +6 -1
- package/templates/applications/miso-controller/application.yaml +96 -1
- package/templates/applications/miso-controller/env.template +63 -37
- package/templates/applications/miso-controller/rbac.yaml +17 -0
- package/templates/external-system/external-datasource.yaml.hbs +7 -1
- package/templates/marketplace/main.json +73 -225
- package/templates/python/Dockerfile.hbs +2 -0
- package/templates/python/docker-compose.hbs +1 -1
- package/templates/typescript/Dockerfile.hbs +2 -0
- package/templates/typescript/docker-compose.hbs +12 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +0 -34
- /package/{lib/programmatic/help-content → docs/builder-help/content}/channel-onboarding.md +0 -0
- /package/{lib/programmatic/help-content → docs/builder-help/content}/cip-overview.md +0 -0
- /package/{lib/programmatic/help-content → docs/builder-help/content}/connected-system-ui.md +0 -0
- /package/{lib/programmatic/help-content → docs/builder-help/content}/dimensions-guide.md +0 -0
- /package/{lib/programmatic/help-content → docs/builder-help/content}/enterprise-sync-fabrix.md +0 -0
- /package/{lib/programmatic/help-content → docs/builder-help/content}/overview.md +0 -0
- /package/{lib/programmatic/help-content → docs/builder-help/content}/subscription-guide.md +0 -0
- /package/{lib/programmatic/help-content → docs/builder-help/content}/workflow.md +0 -0
|
@@ -29,7 +29,6 @@ standardUpInfraEnsureKeys:
|
|
|
29
29
|
- databases-dataplane-3-urlKeyVault
|
|
30
30
|
- databases-dataplane-3-passwordKeyVault
|
|
31
31
|
# Miso-controller Entra onboarding (vendor app); required for aifabrix resolve miso-controller
|
|
32
|
-
- entra-callback-state-secret
|
|
33
32
|
- entra-callback-uri
|
|
34
33
|
- entra-client-idKeyVault
|
|
35
34
|
- entra-client-secretKeyVault
|
|
@@ -106,6 +105,9 @@ parameters:
|
|
|
106
105
|
value: 'redis://${REDIS_HOST}:${REDIS_PORT}'
|
|
107
106
|
ensureOn: [upInfra, resolveApp]
|
|
108
107
|
azure:
|
|
108
|
+
vaultSecretName: redis-url
|
|
109
|
+
legacyVaultSecretNames:
|
|
110
|
+
- redis-urlKeyVault
|
|
109
111
|
notes: >-
|
|
110
112
|
Local up-infra resolves the REDIS_HOST/REDIS_PORT placeholders. Azure application deploy
|
|
111
113
|
must leave this key absent so the Azure SDK derives the rediss URL and credential.
|
|
@@ -349,20 +351,6 @@ parameters:
|
|
|
349
351
|
|
|
350
352
|
# Miso-controller Entra ID onboarding (vendor multi-tenant app). Empty client/callback values
|
|
351
353
|
# allow local resolve and start-dev; set real values before Entra admin-consent flows.
|
|
352
|
-
- key: entra-callback-state-secret
|
|
353
|
-
category: Microsoft Entra ID
|
|
354
|
-
sensitive: true
|
|
355
|
-
valueSource: generated
|
|
356
|
-
requiredOnSystemOnboarding: true
|
|
357
|
-
scope: system
|
|
358
|
-
generator:
|
|
359
|
-
type: randomBytes32
|
|
360
|
-
ensureOn: [upInfra, resolveApp]
|
|
361
|
-
azure:
|
|
362
|
-
notes: >-
|
|
363
|
-
Shared HMAC secret (min 16 chars) for OAuth state between controller and Mori callback;
|
|
364
|
-
maps to ENTRA_CALLBACK_STATE_SECRET in miso-controller env.template.
|
|
365
|
-
|
|
366
354
|
- key: entra-callback-uri
|
|
367
355
|
category: Microsoft Entra ID
|
|
368
356
|
sensitive: false
|
|
@@ -441,8 +429,9 @@ parameters:
|
|
|
441
429
|
# side is decrypted by the other. The read was already happening in the shipped template
|
|
442
430
|
# and the policy denied it. Declared rather than silently permitted, and kept to the one
|
|
443
431
|
# application that needs it instead of moving the key to a scope that grants everyone.
|
|
444
|
-
|
|
432
|
+
visibility:
|
|
445
433
|
- dataplane
|
|
434
|
+
- mori-controller
|
|
446
435
|
scope: app
|
|
447
436
|
generator:
|
|
448
437
|
type: randomBytes32
|
|
@@ -454,6 +443,32 @@ parameters:
|
|
|
454
443
|
notes: >-
|
|
455
444
|
32-byte secret as base64; generated on first ensure. Rotate in production.
|
|
456
445
|
|
|
446
|
+
- key: integration-server-secrets-encryptionKeyVault
|
|
447
|
+
ownerAppKey: integration-server
|
|
448
|
+
# Deliberately NOT shared with any other app, which is the point of the row.
|
|
449
|
+
# An integrator installation hands this key to every developer it provisions: it is
|
|
450
|
+
# written into each managed ~/.aifabrix/config.yaml as `secrets-encryption`, so the
|
|
451
|
+
# CLI can decrypt what that installation's own secrets API encrypted. A key shared
|
|
452
|
+
# with another application would therefore be readable by everyone holding a shell
|
|
453
|
+
# in that container, and one leak would reach every installation using it.
|
|
454
|
+
# One installation, one key, so the blast radius stays inside it.
|
|
455
|
+
#
|
|
456
|
+
# Before this row existed, integration-server's env.template read
|
|
457
|
+
# `kv://builder-server-secrets-encryptionKeyVault` — another application's key.
|
|
458
|
+
# That resolves only by being granted, and granting it grants exactly the access
|
|
459
|
+
# above; without a grant it silently generated an unrelated value instead, so the
|
|
460
|
+
# two server types drifted apart with nothing reporting it.
|
|
461
|
+
scope: app
|
|
462
|
+
generator:
|
|
463
|
+
type: randomBytes32
|
|
464
|
+
ensureOn: [upInfra, resolveApp]
|
|
465
|
+
azure:
|
|
466
|
+
vaultSecretName: integration-server-secrets-encryptionKeyVault
|
|
467
|
+
notes: >-
|
|
468
|
+
32-byte secret as base64; generated on first ensure, per installation. Rotating it
|
|
469
|
+
requires re-running configuration sync so every managed config.yaml is rewritten;
|
|
470
|
+
secrets already stored by that installation do not survive the rotation.
|
|
471
|
+
|
|
457
472
|
# Local kv:// name matches miso-controller env.template (JWT_SECRET); not the generic {appKey}-secrets-jwtKeyVault Azure name.
|
|
458
473
|
- key: miso-controller-jwt-secretKeyVault
|
|
459
474
|
ownerAppKey: miso-controller
|
|
@@ -582,6 +597,7 @@ parameters:
|
|
|
582
597
|
- key: miso-controller-client-idKeyVault
|
|
583
598
|
ownerAppKey: miso-controller
|
|
584
599
|
scope: app
|
|
600
|
+
sensitive: false
|
|
585
601
|
generator:
|
|
586
602
|
type: literal
|
|
587
603
|
value: 'miso-controller-miso-miso-controller'
|
|
@@ -603,10 +619,35 @@ parameters:
|
|
|
603
619
|
Per-app OAuth client secret used by miso-controller for service-to-service auth (MISO_CLIENTSECRET).
|
|
604
620
|
Generated on first ensure for local bootstrap.
|
|
605
621
|
|
|
622
|
+
# Builder API ↔ controller OAuth. These are explicit declarations rather than catch-all
|
|
623
|
+
# matches so the backup catalog records the owner and canonical names unambiguously.
|
|
624
|
+
- key: builder-api-client-idKeyVault
|
|
625
|
+
ownerAppKey: builder-api
|
|
626
|
+
scope: app
|
|
627
|
+
sensitive: false
|
|
628
|
+
generator:
|
|
629
|
+
type: emptyString
|
|
630
|
+
ensureOn: [resolveApp]
|
|
631
|
+
azure:
|
|
632
|
+
vaultSecretName: builder-api-client-idKeyVault
|
|
633
|
+
notes: Per-app OAuth client id issued when builder-api is registered with Miso.
|
|
634
|
+
|
|
635
|
+
- key: builder-api-client-secretKeyVault
|
|
636
|
+
ownerAppKey: builder-api
|
|
637
|
+
scope: app
|
|
638
|
+
sensitive: true
|
|
639
|
+
generator:
|
|
640
|
+
type: emptyString
|
|
641
|
+
ensureOn: [resolveApp]
|
|
642
|
+
azure:
|
|
643
|
+
vaultSecretName: builder-api-client-secretKeyVault
|
|
644
|
+
notes: Per-app OAuth client secret issued when builder-api is registered with Miso.
|
|
645
|
+
|
|
606
646
|
# Dataplane ↔ controller OAuth (builder/dataplane env.template MISO_CLIENTID / MISO_CLIENTSECRET).
|
|
607
647
|
- key: dataplane-client-idKeyVault
|
|
608
648
|
ownerAppKey: dataplane
|
|
609
649
|
scope: app
|
|
650
|
+
sensitive: false
|
|
610
651
|
generator:
|
|
611
652
|
type: literal
|
|
612
653
|
value: 'miso-controller-dev-dataplane'
|
|
@@ -640,18 +681,39 @@ parameters:
|
|
|
640
681
|
notes: Empty locally; set when calling Mori with API key auth.
|
|
641
682
|
|
|
642
683
|
# Public, but a security-critical trust anchor. Never derive it from a pasted JWT.
|
|
684
|
+
#
|
|
685
|
+
# `sensitive: true` on a public key is deliberate -- 227.1 made Miso verify licences against a
|
|
686
|
+
# PINNED key precisely because a key travelling inside the token it verifies proves nothing, so
|
|
687
|
+
# this value must be protected from tampering even though disclosing it costs nothing.
|
|
688
|
+
#
|
|
689
|
+
# It is owned by `miso-controller` rather than left system-scoped because a system-scoped
|
|
690
|
+
# sensitive secret is readable by NO application (`forbidden-system-secret`). Measured on
|
|
691
|
+
# aifabrix-ce-16 2026-09-27: miso-controller declares MORI_LICENSE_PUBLIC_KEY in its manifest, yet
|
|
692
|
+
# the key was absent from its 70 registry rows and from its snapshot, so the installation could
|
|
693
|
+
# never have verified a licence. Ownership is what makes a trust anchor readable by the service
|
|
694
|
+
# whose trust it anchors -- the same correction already applied to secrets-policyPrivateKeyVault.
|
|
643
695
|
- key: mori-license-public-keyKeyVault
|
|
644
696
|
category: Mori
|
|
697
|
+
ownerAppKey: miso-controller
|
|
645
698
|
sensitive: true
|
|
646
699
|
valueSource: optionalInput
|
|
647
700
|
requiredOnSystemOnboarding: false
|
|
648
|
-
scope:
|
|
701
|
+
scope: app
|
|
702
|
+
# The public half of the Mori licence pair above, so the key Miso verifies with cannot drift
|
|
703
|
+
# from the key Mori signs with. Was `emptyString`: the two halves came from unrelated places
|
|
704
|
+
# and an installation could hold a perfectly valid public key belonging to a different private
|
|
705
|
+
# key, which verifies nothing and reports no error.
|
|
706
|
+
#
|
|
707
|
+
# Rotating an installation that already holds a value here means clearing BOTH halves
|
|
708
|
+
# together — the generator is get-or-create, so replacing one alone leaves a mismatched pair.
|
|
649
709
|
generator:
|
|
650
|
-
type:
|
|
710
|
+
type: rsaKeyPair
|
|
711
|
+
pairId: mori-license-signing
|
|
712
|
+
part: public
|
|
651
713
|
ensureOn: [upInfra, resolveApp]
|
|
652
714
|
azure:
|
|
653
715
|
vaultSecretName: mori-license-public-keyKeyVault
|
|
654
|
-
notes:
|
|
716
|
+
notes: SPKI PEM public half of the Mori licence signing pair; linked to secrets-licensePrivateKeyVault.
|
|
655
717
|
|
|
656
718
|
- key: appinsights-connectionStringKeyVault
|
|
657
719
|
category: Observability
|
|
@@ -693,7 +755,7 @@ parameters:
|
|
|
693
755
|
vaultSecretName: loganalytics-workspace-id
|
|
694
756
|
notes: Azure SDK-derived Log Analytics workspace customer identifier.
|
|
695
757
|
|
|
696
|
-
- key:
|
|
758
|
+
- key: azure-openai/endpoint
|
|
697
759
|
category: Azure OpenAI
|
|
698
760
|
sensitive: false
|
|
699
761
|
valueSource: optionalInput
|
|
@@ -703,10 +765,10 @@ parameters:
|
|
|
703
765
|
type: emptyString
|
|
704
766
|
ensureOn: [resolveApp]
|
|
705
767
|
azure:
|
|
706
|
-
vaultSecretName:
|
|
707
|
-
notes: Azure OpenAI endpoint produced by the
|
|
768
|
+
vaultSecretName: dev-dataplane-azure-openai-endpoint
|
|
769
|
+
notes: Azure OpenAI endpoint produced by infrastructure at the standard dev Dataplane address.
|
|
708
770
|
|
|
709
|
-
- key:
|
|
771
|
+
- key: azure-openai/apiKey
|
|
710
772
|
category: Azure OpenAI
|
|
711
773
|
sensitive: true
|
|
712
774
|
valueSource: optionalInput
|
|
@@ -716,21 +778,8 @@ parameters:
|
|
|
716
778
|
type: emptyString
|
|
717
779
|
ensureOn: [resolveApp]
|
|
718
780
|
azure:
|
|
719
|
-
vaultSecretName:
|
|
720
|
-
notes: Azure OpenAI API key produced by the
|
|
721
|
-
|
|
722
|
-
# Dataplane builder/dataplane env.template (AI/LLM); optional until OpenAI or Azure OpenAI is configured.
|
|
723
|
-
- key: secrets-openaiApiKeyVault
|
|
724
|
-
category: OpenAI
|
|
725
|
-
sensitive: true
|
|
726
|
-
valueSource: optionalInput
|
|
727
|
-
requiredOnSystemOnboarding: false
|
|
728
|
-
scope: system
|
|
729
|
-
generator:
|
|
730
|
-
type: emptyString
|
|
731
|
-
ensureOn: [resolveApp]
|
|
732
|
-
azure:
|
|
733
|
-
notes: Optional shared OpenAI API key; empty until supplied and never auto-generated.
|
|
781
|
+
vaultSecretName: dev-dataplane-azure-openai-api-key
|
|
782
|
+
notes: Azure OpenAI API key produced by infrastructure at the standard dev Dataplane address.
|
|
734
783
|
|
|
735
784
|
- key: azure-openaiapi-urlKeyVault
|
|
736
785
|
scope: app
|
|
@@ -740,17 +789,13 @@ parameters:
|
|
|
740
789
|
azure:
|
|
741
790
|
notes: Empty until set; Azure OpenAI endpoint URL.
|
|
742
791
|
|
|
743
|
-
- key: secrets-azureOpenaiApiKeyVault
|
|
744
|
-
scope: app
|
|
745
|
-
generator:
|
|
746
|
-
type: emptyString
|
|
747
|
-
ensureOn: [upInfra, resolveApp]
|
|
748
|
-
azure:
|
|
749
|
-
notes: Empty until set; user-supplied Azure OpenAI API key (not auto-generated).
|
|
750
|
-
|
|
751
792
|
# Dataplane RS256 signing identity. The two rows are generated as one linked pair.
|
|
752
793
|
- key: secrets-certificatePrivateKeyVault
|
|
753
794
|
ownerAppKey: dataplane
|
|
795
|
+
# Deliberately NOT shared with mori-controller. `readability-real-catalog.test.ts` asserts
|
|
796
|
+
# "denies mori signing licences with the dataplane signing key" — Mori's manifest pointing
|
|
797
|
+
# MORI_LICENSE_PRIVATE_KEY at this key is the misconfiguration, not the denial. The fix is a
|
|
798
|
+
# mori-controller-owned licence key and a manifest change, never widening this entry.
|
|
754
799
|
scope: app
|
|
755
800
|
generator:
|
|
756
801
|
type: rsaKeyPair
|
|
@@ -761,6 +806,66 @@ parameters:
|
|
|
761
806
|
vaultSecretName: secrets-certificatePrivateKeyVault
|
|
762
807
|
notes: PKCS#8 PEM private key generated with the matching public key.
|
|
763
808
|
|
|
809
|
+
# Mori's policy signing key. Present in every installation's vault but absent from this catalog,
|
|
810
|
+
# so it fell through to the `^[a-zA-Z0-9_-]+KeyVault$` catch-all — `scope: app` with no owner,
|
|
811
|
+
# which `resolveOwnershipDecision` cannot classify and the policy therefore denies to everyone.
|
|
812
|
+
#
|
|
813
|
+
# Measured on aifabrix-ce-16, 2026-09-26: the secret exists, Mori reads it today through an App
|
|
814
|
+
# Service Key Vault reference, and bootstrap omitted it. That is the same key whose absence
|
|
815
|
+
# previously failed Mori's signing health check.
|
|
816
|
+
- key: secrets-policyPrivateKeyVault
|
|
817
|
+
ownerAppKey: mori-controller
|
|
818
|
+
scope: app
|
|
819
|
+
sensitive: true
|
|
820
|
+
generator:
|
|
821
|
+
type: rsaKeyPair
|
|
822
|
+
pairId: mori-policy-signing
|
|
823
|
+
part: private
|
|
824
|
+
ensureOn: [resolveApp]
|
|
825
|
+
azure:
|
|
826
|
+
vaultSecretName: secrets-policyPrivateKeyVault
|
|
827
|
+
notes: PKCS#8 PEM private key for Mori policy signing; MORI_POLICY_KEY_ID names the pair.
|
|
828
|
+
|
|
829
|
+
# Mori's LICENCE signing key, which is not its policy signing key and not the dataplane's.
|
|
830
|
+
#
|
|
831
|
+
# `subscription-license.operations.ts` refuses to issue at all without it:
|
|
832
|
+
# if (!privateKey) throw ErrorFactory.internalServerError('License signing is unavailable')
|
|
833
|
+
# and until this entry existed there was nothing for it to read. Mori's manifest pointed
|
|
834
|
+
# MORI_LICENSE_PRIVATE_KEY at `secrets-certificatePrivateKeyVault`, which the dataplane owns, so
|
|
835
|
+
# the read was denied -- correctly. An existing test (`denies mori signing licences with the
|
|
836
|
+
# dataplane signing key`) pins that denial, so the fix is a key Mori owns, never a wider grant.
|
|
837
|
+
#
|
|
838
|
+
# `emptyString` rather than `rsaKeyPair`: the operator supplies the pair, because whoever holds
|
|
839
|
+
# this key decides which licences an installation will believe. Generating it during onboarding
|
|
840
|
+
# would make the platform mint its own trust root as a side effect of deployment. Onboarding
|
|
841
|
+
# creates the placeholder, `aifabrix env secret push` writes the real value, and create-if-absent
|
|
842
|
+
# then leaves it alone. The verifying half is `mori-license-public-keyKeyVault`, pinned to
|
|
843
|
+
# miso-controller; a pair is only useful if both halves are readable by their own service.
|
|
844
|
+
- key: secrets-licensePrivateKeyVault
|
|
845
|
+
category: Mori
|
|
846
|
+
ownerAppKey: mori-controller
|
|
847
|
+
scope: app
|
|
848
|
+
sensitive: true
|
|
849
|
+
valueSource: optionalInput
|
|
850
|
+
requiredOnSystemOnboarding: false
|
|
851
|
+
# Generated as one linked pair with mori-license-public-keyKeyVault, the same way the
|
|
852
|
+
# dataplane's signing identity is. Was `emptyString`, which meant an installation that
|
|
853
|
+
# repointed Mori at this key got nothing and `subscription-license.operations.ts` refused
|
|
854
|
+
# with "License signing is unavailable" -- so the only working configuration was the wrong
|
|
855
|
+
# one: Mori signing with the DATAPLANE's key via secrets-certificatePrivateKeyVault.
|
|
856
|
+
#
|
|
857
|
+
# Mori and the dataplane must not share a signing identity. Sharing one means the dataplane
|
|
858
|
+
# holds a key that mints licences, and the two services have completely different blast
|
|
859
|
+
# radii. Mori is the licence server; the dataplane runs customer workloads.
|
|
860
|
+
generator:
|
|
861
|
+
type: rsaKeyPair
|
|
862
|
+
pairId: mori-license-signing
|
|
863
|
+
part: private
|
|
864
|
+
ensureOn: [resolveApp]
|
|
865
|
+
azure:
|
|
866
|
+
vaultSecretName: secrets-licensePrivateKeyVault
|
|
867
|
+
notes: PKCS#8 PEM private key for Mori licence signing; MORI_LICENSE_KEY_ID names the pair.
|
|
868
|
+
|
|
764
869
|
- key: secrets-certificatePublicKeyVault
|
|
765
870
|
ownerAppKey: dataplane
|
|
766
871
|
scope: app
|
|
@@ -794,18 +899,6 @@ parameters:
|
|
|
794
899
|
Optional local testing/development bearer bypass. A supplied local value is resolved; when absent,
|
|
795
900
|
local and Azure application deployment resolve it as empty and do not fail.
|
|
796
901
|
|
|
797
|
-
- key: mori-callback-api-keyKeyVault
|
|
798
|
-
ownerAppKey: miso-controller
|
|
799
|
-
scope: app
|
|
800
|
-
generator:
|
|
801
|
-
type: randomBytes32
|
|
802
|
-
ensureOn: [resolveApp]
|
|
803
|
-
azure:
|
|
804
|
-
vaultSecretName: mori-callback-api-keyKeyVault
|
|
805
|
-
legacyVaultSecretNames:
|
|
806
|
-
- marketplace-mori-callback-api-key
|
|
807
|
-
notes: Miso Controller callback credential; generated only when its resolved manifest requires it.
|
|
808
|
-
|
|
809
902
|
# App semver when env.template / conversion yields kv://version (local secrets backfill).
|
|
810
903
|
- key: version
|
|
811
904
|
scope: app
|
|
@@ -825,8 +918,12 @@ parameters:
|
|
|
825
918
|
type: databaseUrl
|
|
826
919
|
ensureOn: [upInfra, resolveApp]
|
|
827
920
|
azure:
|
|
828
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-urlKeyVault'
|
|
921
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
829
922
|
legacyVaultSecretNames:
|
|
923
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
924
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
925
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
926
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
830
927
|
- '{key}'
|
|
831
928
|
- '{serviceName}-databases-0-urlKeyVault'
|
|
832
929
|
|
|
@@ -837,8 +934,12 @@ parameters:
|
|
|
837
934
|
type: databasePassword
|
|
838
935
|
ensureOn: [upInfra, resolveApp]
|
|
839
936
|
azure:
|
|
840
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-passwordKeyVault'
|
|
937
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
841
938
|
legacyVaultSecretNames:
|
|
939
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
940
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
941
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
942
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
842
943
|
- '{key}'
|
|
843
944
|
|
|
844
945
|
- key: databases-miso-controller-1-urlKeyVault
|
|
@@ -848,8 +949,12 @@ parameters:
|
|
|
848
949
|
type: databaseUrl
|
|
849
950
|
ensureOn: [upInfra, resolveApp]
|
|
850
951
|
azure:
|
|
851
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-urlKeyVault'
|
|
952
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
852
953
|
legacyVaultSecretNames:
|
|
954
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
955
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
956
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
957
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
853
958
|
- '{key}'
|
|
854
959
|
- '{serviceName}-databases-1-urlKeyVault'
|
|
855
960
|
|
|
@@ -860,9 +965,120 @@ parameters:
|
|
|
860
965
|
type: databasePassword
|
|
861
966
|
ensureOn: [upInfra, resolveApp]
|
|
862
967
|
azure:
|
|
863
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-passwordKeyVault'
|
|
968
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
969
|
+
legacyVaultSecretNames:
|
|
970
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
971
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
972
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
973
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
974
|
+
- '{key}'
|
|
975
|
+
|
|
976
|
+
# Installed Dataplane stacks used semantic database names before the environment-scoped
|
|
977
|
+
# convention. Keep the exact inventory here so onboarding can copy each value to its canonical
|
|
978
|
+
# name without guessing which database slot it belongs to.
|
|
979
|
+
- key: databases-dataplane-0-urlKeyVault
|
|
980
|
+
ownerAppKey: dataplane
|
|
981
|
+
scope: app
|
|
982
|
+
generator:
|
|
983
|
+
type: databaseUrl
|
|
984
|
+
ensureOn: [upInfra, resolveApp]
|
|
985
|
+
azure:
|
|
986
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
987
|
+
legacyVaultSecretNames:
|
|
988
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
989
|
+
- '{key}'
|
|
990
|
+
- dataplane-connection-string
|
|
991
|
+
|
|
992
|
+
- key: databases-dataplane-0-passwordKeyVault
|
|
993
|
+
ownerAppKey: dataplane
|
|
994
|
+
scope: app
|
|
995
|
+
generator:
|
|
996
|
+
type: databasePassword
|
|
997
|
+
ensureOn: [upInfra, resolveApp]
|
|
998
|
+
azure:
|
|
999
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
864
1000
|
legacyVaultSecretNames:
|
|
1001
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
865
1002
|
- '{key}'
|
|
1003
|
+
- dataplane-password
|
|
1004
|
+
|
|
1005
|
+
- key: databases-dataplane-1-urlKeyVault
|
|
1006
|
+
ownerAppKey: dataplane
|
|
1007
|
+
scope: app
|
|
1008
|
+
generator:
|
|
1009
|
+
type: databaseUrl
|
|
1010
|
+
ensureOn: [upInfra, resolveApp]
|
|
1011
|
+
azure:
|
|
1012
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
1013
|
+
legacyVaultSecretNames:
|
|
1014
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1015
|
+
- '{key}'
|
|
1016
|
+
- dataplane-vector-connection-string
|
|
1017
|
+
|
|
1018
|
+
- key: databases-dataplane-1-passwordKeyVault
|
|
1019
|
+
ownerAppKey: dataplane
|
|
1020
|
+
scope: app
|
|
1021
|
+
generator:
|
|
1022
|
+
type: databasePassword
|
|
1023
|
+
ensureOn: [upInfra, resolveApp]
|
|
1024
|
+
azure:
|
|
1025
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1026
|
+
legacyVaultSecretNames:
|
|
1027
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1028
|
+
- '{key}'
|
|
1029
|
+
- dataplane-vector-password
|
|
1030
|
+
|
|
1031
|
+
- key: databases-dataplane-2-urlKeyVault
|
|
1032
|
+
ownerAppKey: dataplane
|
|
1033
|
+
scope: app
|
|
1034
|
+
generator:
|
|
1035
|
+
type: databaseUrl
|
|
1036
|
+
ensureOn: [upInfra, resolveApp]
|
|
1037
|
+
azure:
|
|
1038
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
1039
|
+
legacyVaultSecretNames:
|
|
1040
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1041
|
+
- '{key}'
|
|
1042
|
+
- dataplane-logs-connection-string
|
|
1043
|
+
|
|
1044
|
+
- key: databases-dataplane-2-passwordKeyVault
|
|
1045
|
+
ownerAppKey: dataplane
|
|
1046
|
+
scope: app
|
|
1047
|
+
generator:
|
|
1048
|
+
type: databasePassword
|
|
1049
|
+
ensureOn: [upInfra, resolveApp]
|
|
1050
|
+
azure:
|
|
1051
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1052
|
+
legacyVaultSecretNames:
|
|
1053
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1054
|
+
- '{key}'
|
|
1055
|
+
- dataplane-logs-password
|
|
1056
|
+
|
|
1057
|
+
- key: databases-dataplane-3-urlKeyVault
|
|
1058
|
+
ownerAppKey: dataplane
|
|
1059
|
+
scope: app
|
|
1060
|
+
generator:
|
|
1061
|
+
type: databaseUrl
|
|
1062
|
+
ensureOn: [upInfra, resolveApp]
|
|
1063
|
+
azure:
|
|
1064
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
1065
|
+
legacyVaultSecretNames:
|
|
1066
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1067
|
+
- '{key}'
|
|
1068
|
+
- dataplane-records-connection-string
|
|
1069
|
+
|
|
1070
|
+
- key: databases-dataplane-3-passwordKeyVault
|
|
1071
|
+
ownerAppKey: dataplane
|
|
1072
|
+
scope: app
|
|
1073
|
+
generator:
|
|
1074
|
+
type: databasePassword
|
|
1075
|
+
ensureOn: [upInfra, resolveApp]
|
|
1076
|
+
azure:
|
|
1077
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1078
|
+
legacyVaultSecretNames:
|
|
1079
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1080
|
+
- '{key}'
|
|
1081
|
+
- dataplane-records-password
|
|
866
1082
|
|
|
867
1083
|
# Per-index database secrets. Index must match requires.databases order in application.yaml.
|
|
868
1084
|
- keyPattern: '^databases-[a-z0-9-]+-\d+-urlKeyVault$'
|
|
@@ -871,8 +1087,12 @@ parameters:
|
|
|
871
1087
|
type: databaseUrl
|
|
872
1088
|
ensureOn: [upInfra, resolveApp]
|
|
873
1089
|
azure:
|
|
874
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-urlKeyVault'
|
|
1090
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
875
1091
|
legacyVaultSecretNames:
|
|
1092
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
1093
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
1094
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1095
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
876
1096
|
- '{key}'
|
|
877
1097
|
notes: The manifest key stays logical; the app-prefixed name is the physical vault key.
|
|
878
1098
|
|
|
@@ -882,12 +1102,26 @@ parameters:
|
|
|
882
1102
|
type: databasePassword
|
|
883
1103
|
ensureOn: [upInfra, resolveApp]
|
|
884
1104
|
azure:
|
|
885
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-passwordKeyVault'
|
|
1105
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
886
1106
|
legacyVaultSecretNames:
|
|
1107
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
1108
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
1109
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1110
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
887
1111
|
- '{key}'
|
|
888
1112
|
|
|
1113
|
+
# Addresses, not credentials.
|
|
1114
|
+
#
|
|
1115
|
+
# These defaulted to sensitive (`sensitive` is absent, and the service reads `entry.sensitive !== false`),
|
|
1116
|
+
# so the system-secrets list API withheld the VALUE of a URL, a hostname and a virtual directory. Six
|
|
1117
|
+
# literal entries — frontdoor-url, frontdoor-host, keycloak-web-server-url,
|
|
1118
|
+
# keycloak-internal-server-url, keycloak-vdir-public, miso-controller-web-server-url and friends —
|
|
1119
|
+
# exist only to override that one key at a time, which is the hardcoding this convention removes.
|
|
1120
|
+
# An address is operator-facing by nature: hiding it makes an installation harder to diagnose and
|
|
1121
|
+
# protects nothing.
|
|
889
1122
|
# Keycloak and other *-url keys (non-database).
|
|
890
1123
|
- keyPattern: '^keycloak-.+-url$'
|
|
1124
|
+
sensitive: false
|
|
891
1125
|
scope: shared-service
|
|
892
1126
|
generator:
|
|
893
1127
|
type: emptyString
|
|
@@ -895,6 +1129,7 @@ parameters:
|
|
|
895
1129
|
|
|
896
1130
|
# App-scoped URL placeholders (filled at resolve / deploy).
|
|
897
1131
|
- keyPattern: '^[a-z0-9-]+-url$'
|
|
1132
|
+
sensitive: false
|
|
898
1133
|
scope: app
|
|
899
1134
|
generator:
|
|
900
1135
|
type: emptyString
|
|
@@ -902,6 +1137,7 @@ parameters:
|
|
|
902
1137
|
|
|
903
1138
|
# Deploy manifest maps frontDoorRouting.host templates to this secret (Azure / pipeline).
|
|
904
1139
|
- keyPattern: '^[a-z0-9-]+-frontdoor-routing-host$'
|
|
1140
|
+
sensitive: false
|
|
905
1141
|
scope: app
|
|
906
1142
|
generator:
|
|
907
1143
|
type: emptyString
|
|
@@ -910,32 +1146,146 @@ parameters:
|
|
|
910
1146
|
notes: Hostname template for Traefik / Front Door; filled at deploy.
|
|
911
1147
|
|
|
912
1148
|
- keyPattern: '^[a-z0-9-]+-vdir-public$'
|
|
1149
|
+
sensitive: false
|
|
913
1150
|
scope: app
|
|
914
1151
|
generator:
|
|
915
1152
|
type: emptyString
|
|
916
1153
|
ensureOn: [resolveApp]
|
|
917
1154
|
|
|
918
1155
|
- keyPattern: '^[a-z0-9-]+-vdir-internal$'
|
|
1156
|
+
sensitive: false
|
|
919
1157
|
scope: app
|
|
920
1158
|
generator:
|
|
921
1159
|
type: emptyString
|
|
922
1160
|
ensureOn: [resolveApp]
|
|
923
1161
|
|
|
924
1162
|
- keyPattern: '^[a-z0-9-]+-host-public$'
|
|
1163
|
+
sensitive: false
|
|
925
1164
|
scope: app
|
|
926
1165
|
generator:
|
|
927
1166
|
type: emptyString
|
|
928
1167
|
ensureOn: [resolveApp]
|
|
929
1168
|
|
|
930
1169
|
- keyPattern: '^[a-z0-9-]+-host-internal$'
|
|
1170
|
+
sensitive: false
|
|
931
1171
|
scope: app
|
|
932
1172
|
generator:
|
|
933
1173
|
type: emptyString
|
|
934
1174
|
ensureOn: [resolveApp]
|
|
935
1175
|
|
|
936
|
-
#
|
|
937
|
-
|
|
1176
|
+
# Secrets that are genuinely generated here, declared explicitly because the catch-all below no
|
|
1177
|
+
# longer invents values. Each is a shared secret with no other issuer: nothing outside this
|
|
1178
|
+
# catalog mints them, so an empty value would leave the consumer with nothing to verify against.
|
|
1179
|
+
- key: notification-event-webhook-secretKeyVault
|
|
938
1180
|
scope: app
|
|
939
1181
|
generator:
|
|
940
1182
|
type: randomBytes32
|
|
941
1183
|
ensureOn: [resolveApp]
|
|
1184
|
+
azure:
|
|
1185
|
+
vaultSecretName: notification-event-webhook-secretKeyVault
|
|
1186
|
+
notes: Shared secret signing notification webhook callbacks; generated, never supplied.
|
|
1187
|
+
|
|
1188
|
+
- key: secrets-encryptionKeyVault
|
|
1189
|
+
scope: app
|
|
1190
|
+
generator:
|
|
1191
|
+
type: randomBytes32
|
|
1192
|
+
ensureOn: [resolveApp]
|
|
1193
|
+
azure:
|
|
1194
|
+
vaultSecretName: secrets-encryptionKeyVault
|
|
1195
|
+
notes: Application-scoped encryption key; generated, never supplied.
|
|
1196
|
+
|
|
1197
|
+
- key: miso-controller-api-key-secretKeyVault
|
|
1198
|
+
scope: app
|
|
1199
|
+
generator:
|
|
1200
|
+
type: randomBytes32
|
|
1201
|
+
ensureOn: [resolveApp]
|
|
1202
|
+
azure:
|
|
1203
|
+
vaultSecretName: miso-controller-api-key-secretKeyVault
|
|
1204
|
+
notes: Generated API key for test/integration apps; generated, never supplied.
|
|
1205
|
+
|
|
1206
|
+
# `-idKeyVault` and `-nameKeyVault` are NOT secrets.
|
|
1207
|
+
#
|
|
1208
|
+
# An identifier and a name are operator-facing: a client ID, a tenant ID, a subscription ID, a
|
|
1209
|
+
# service name. They live in the same store as the secrets because they arrive the same way, but
|
|
1210
|
+
# there is nothing to withhold, and withholding them makes an installation harder to read.
|
|
1211
|
+
#
|
|
1212
|
+
# These two rows replace five literal entries that existed only to set `sensitive: false` on one
|
|
1213
|
+
# key each — `keycloak-client-idKeyVault`, `entra-client-idKeyVault`,
|
|
1214
|
+
# `azure-subscription-idKeyVault`, `azure-tenant-idKeyVault`, `azure-service-nameKeyVault`. The
|
|
1215
|
+
# convention now carries the decision, so a customer's own `myapp-tenant-idKeyVault` is readable
|
|
1216
|
+
# without an edit here.
|
|
1217
|
+
#
|
|
1218
|
+
# ORDER MATTERS: `findCatalogEntry` checks exact keys, then patterns in FILE ORDER and returns the
|
|
1219
|
+
# first match. Both suffixes also match the generic `*KeyVault` catch-all below, so they have to
|
|
1220
|
+
# stay above it or they inherit `sensitive: true` and the convention silently does nothing.
|
|
1221
|
+
- keyPattern: '^[a-zA-Z0-9_-]+-idKeyVault$'
|
|
1222
|
+
scope: app
|
|
1223
|
+
sensitive: false
|
|
1224
|
+
generator:
|
|
1225
|
+
type: emptyString
|
|
1226
|
+
ensureOn: [resolveApp]
|
|
1227
|
+
|
|
1228
|
+
- keyPattern: '^[a-zA-Z0-9_-]+-nameKeyVault$'
|
|
1229
|
+
scope: app
|
|
1230
|
+
sensitive: false
|
|
1231
|
+
generator:
|
|
1232
|
+
type: emptyString
|
|
1233
|
+
ensureOn: [resolveApp]
|
|
1234
|
+
|
|
1235
|
+
# Remaining *KeyVault secrets — created EMPTY, then supplied.
|
|
1236
|
+
#
|
|
1237
|
+
# This generated `randomBytes32`, so any `kv://<anything>KeyVault` key the catalog did not name
|
|
1238
|
+
# explicitly received 32 random bytes — 44 base64 characters — and the reference resolved to a
|
|
1239
|
+
# value that was never a credential anybody issued.
|
|
1240
|
+
#
|
|
1241
|
+
# Measured on installation aifabrix-ce-16, 2026-09-25: `secrets-policyPrivateKeyVault` is Mori's
|
|
1242
|
+
# licence-policy SIGNING KEY and held exactly that, 44 characters and not a PEM. Mori's
|
|
1243
|
+
# `signingKeysHealthCheck` parses the key rather than checking presence, so it reported
|
|
1244
|
+
# `signingKeys` down, the container exited, and the web app answered HTTP 503 on every path for two
|
|
1245
|
+
# days while App Service reported it Running. Mori's own comment had predicted this class in
|
|
1246
|
+
# writing: "the deployment builder provisioned an unknown Key Vault catalog key with a random
|
|
1247
|
+
# 44-character secret rather than failing: present, resolved, and not a private key at all".
|
|
1248
|
+
#
|
|
1249
|
+
# Empty is the correct default for a key nobody here mints. It creates the secret — so `kv://`
|
|
1250
|
+
# resolves and the reference is valid — while leaving the value visibly unset, which is a state an
|
|
1251
|
+
# operator can see and fix. A random value is indistinguishable from a real credential from the
|
|
1252
|
+
# outside, which is precisely what made it expensive.
|
|
1253
|
+
#
|
|
1254
|
+
# The catch-all stays a pattern rather than becoming a list of literals on purpose: a customer
|
|
1255
|
+
# deploying their own application declares its own `kv://` keys, and those must work without being
|
|
1256
|
+
# hardcoded here. Values arrive afterwards through the write-only system-secrets API
|
|
1257
|
+
# (`PUT /api/v1/environments/{envKey}/system-secrets/{catalogKey}`), which is what
|
|
1258
|
+
# aifabrix-builder plan 204.0 builds the CLI for.
|
|
1259
|
+
#
|
|
1260
|
+
# A secret that genuinely has no issuer but must exist gets an explicit `randomBytes32` entry
|
|
1261
|
+
# above. Adding one is the deliberate act; generation is no longer the silent default.
|
|
1262
|
+
- keyPattern: '^[a-zA-Z0-9_-]+KeyVault$'
|
|
1263
|
+
scope: app
|
|
1264
|
+
sensitive: true
|
|
1265
|
+
generator:
|
|
1266
|
+
type: emptyString
|
|
1267
|
+
ensureOn: [resolveApp]
|
|
1268
|
+
|
|
1269
|
+
# Non-secret values in the same store — the suffix carries the sensitivity.
|
|
1270
|
+
#
|
|
1271
|
+
# `*KeyVault` above means "secret": hidden by the list API, write-only through
|
|
1272
|
+
# `PUT /api/v1/environments/{envKey}/system-secrets/{catalogKey}`. `*Param` means the same storage
|
|
1273
|
+
# with nothing to hide: the list API returns the value, because `summarize()` emits `value` only
|
|
1274
|
+
# when `sensitive === false`.
|
|
1275
|
+
#
|
|
1276
|
+
# Why a pattern and not more literals: the suffix used to say nothing about sensitivity, so every
|
|
1277
|
+
# non-secret that happened to end in `KeyVault` needed its own literal row purely to set
|
|
1278
|
+
# `sensitive: false` — `keycloak-client-idKeyVault`, `entra-client-idKeyVault`,
|
|
1279
|
+
# `azure-subscription-idKeyVault`, `azure-tenant-idKeyVault`, `azure-service-nameKeyVault`. Client
|
|
1280
|
+
# IDs, tenant IDs and service names are not credentials, and hardcoding each one does not scale:
|
|
1281
|
+
# a customer deploying their own application cannot get a visible parameter without an edit here.
|
|
1282
|
+
#
|
|
1283
|
+
# With the convention, visibility is a naming decision the application author makes and a reader
|
|
1284
|
+
# can see: name it `…Param` to be readable, `…KeyVault` to be secret. Changing your mind is a
|
|
1285
|
+
# rename, not a catalog change. Both create the entry EMPTY and are supplied afterwards.
|
|
1286
|
+
- keyPattern: '^[a-zA-Z0-9_-]+Param$'
|
|
1287
|
+
scope: app
|
|
1288
|
+
sensitive: false
|
|
1289
|
+
generator:
|
|
1290
|
+
type: emptyString
|
|
1291
|
+
ensureOn: [resolveApp]
|