@aifabrix/builder 2.60.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/api/configuration.api.js +131 -0
- package/lib/api/system-secrets.api.js +72 -0
- 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/build/docker-build-args.js +5 -2
- package/lib/build/index.js +3 -2
- package/lib/build/standard-docker-build.js +2 -2
- package/lib/cli/setup-app.js +5 -0
- package/lib/cli/setup-environment.js +156 -0
- 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/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 +5 -1
- package/lib/core/secrets-env-content.js +5 -1
- 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/generator/index.js +3 -0
- 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-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 +14 -2
- package/lib/schema/external-datasource.schema.json +23 -3
- package/lib/schema/infra.parameter.yaml +388 -38
- package/lib/utils/compose-generate-docker-compose.js +7 -12
- 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/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/prepare-local-data-mount.js +58 -0
- 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 +4 -3
- package/templates/agent-kit/agent-kit.yaml +1 -1
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +2 -1
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +15 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +3 -2
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +6 -2
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +22 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +7 -1
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/testing-playbook.md +117 -0
- package/templates/agent-kit/skills/shared/interaction.md +83 -0
- package/templates/agent-kit/skills/shared/status.md +3 -12
- package/templates/applications/builder-api/application.yaml +1 -1
- package/templates/applications/builder-api/env.template +5 -1
- package/templates/applications/dataplane/application.yaml +1 -1
- package/templates/applications/dataplane/env.template +10 -12
- package/templates/applications/keycloak/application.yaml +6 -1
- package/templates/applications/miso-controller/application.yaml +74 -2
- package/templates/applications/miso-controller/env.template +42 -3
- package/templates/applications/miso-controller/rbac.yaml +17 -0
- package/templates/external-system/external-datasource.yaml.hbs +7 -1
- package/templates/marketplace/main.json +4 -4
- package/templates/python/docker-compose.hbs +1 -1
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +0 -41
- /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
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"key":"external-datasource-schema",
|
|
8
8
|
"name":"External Data Source Configuration Schema",
|
|
9
9
|
"description":"JSON schema for validating ExternalDataSource configuration files",
|
|
10
|
-
"version":"2.9.
|
|
10
|
+
"version":"2.9.13",
|
|
11
11
|
"type":"schema",
|
|
12
12
|
"category":"integration",
|
|
13
13
|
"author":"AI Fabrix Team",
|
|
@@ -31,6 +31,15 @@
|
|
|
31
31
|
"external-system.schema.json"
|
|
32
32
|
],
|
|
33
33
|
"changelog":[
|
|
34
|
+
{
|
|
35
|
+
"version":"2.9.13",
|
|
36
|
+
"date":"2026-09-24T00:00:00Z",
|
|
37
|
+
"changes":[
|
|
38
|
+
"Added fetch.responseType ('json' | 'binary', default json): a file body becomes one binary record with headers and request arguments exposed to fieldMappings while bytes stay out of traces.",
|
|
39
|
+
"Added output.mode 'documents' for entityType documentStorage: binary records are persisted through the document pipeline and emitted as document references; documentStorage.binaryOperationRef may name the datasource's own get for keyed retrieval."
|
|
40
|
+
],
|
|
41
|
+
"breaking":false
|
|
42
|
+
},
|
|
34
43
|
{
|
|
35
44
|
"version":"2.9.12",
|
|
36
45
|
"date":"2026-09-17T00:00:00Z",
|
|
@@ -2739,6 +2748,15 @@
|
|
|
2739
2748
|
},
|
|
2740
2749
|
"httpResponseNormalization":{
|
|
2741
2750
|
"$ref":"#/$defs/httpResponseNormalization"
|
|
2751
|
+
},
|
|
2752
|
+
"responseType":{
|
|
2753
|
+
"type":"string",
|
|
2754
|
+
"enum":[
|
|
2755
|
+
"json",
|
|
2756
|
+
"binary"
|
|
2757
|
+
],
|
|
2758
|
+
"default":"json",
|
|
2759
|
+
"description":"Body contract of the vendor response. 'binary' turns a file body (application/octet-stream, PDF, image ...) into one binary record whose bytes stay out of traces: {_binary:{contentType,size,filename,sha256}, headers:{...}, params:{...}} for map expressions such as raw.headers.AttachmentName or raw.params.PurchaseOrderNumber. A binary Content-Type is promoted automatically when responseType is omitted; declaring 'binary' fails closed when the body is JSON."
|
|
2742
2760
|
}
|
|
2743
2761
|
},
|
|
2744
2762
|
"allOf":[
|
|
@@ -3174,9 +3192,11 @@
|
|
|
3174
3192
|
"mode":{
|
|
3175
3193
|
"type":"string",
|
|
3176
3194
|
"enum":[
|
|
3177
|
-
"records"
|
|
3195
|
+
"records",
|
|
3196
|
+
"documents"
|
|
3178
3197
|
],
|
|
3179
|
-
"default":"records"
|
|
3198
|
+
"default":"records",
|
|
3199
|
+
"description":"'records' emits normalized records. 'documents' (entityType documentStorage only) stores each binary record through the document pipeline (document store, DocumentRecord/registry rows, FK dimensions, ingestion per documentStorage.ingestAfterSync) and emits document references {key, filename, contentType, size, sha256, downloadRef}; IDE simulation never persists."
|
|
3180
3200
|
},
|
|
3181
3201
|
"limit":{
|
|
3182
3202
|
"type":"integer",
|
|
@@ -105,6 +105,9 @@ parameters:
|
|
|
105
105
|
value: 'redis://${REDIS_HOST}:${REDIS_PORT}'
|
|
106
106
|
ensureOn: [upInfra, resolveApp]
|
|
107
107
|
azure:
|
|
108
|
+
vaultSecretName: redis-url
|
|
109
|
+
legacyVaultSecretNames:
|
|
110
|
+
- redis-urlKeyVault
|
|
108
111
|
notes: >-
|
|
109
112
|
Local up-infra resolves the REDIS_HOST/REDIS_PORT placeholders. Azure application deploy
|
|
110
113
|
must leave this key absent so the Azure SDK derives the rediss URL and credential.
|
|
@@ -594,6 +597,7 @@ parameters:
|
|
|
594
597
|
- key: miso-controller-client-idKeyVault
|
|
595
598
|
ownerAppKey: miso-controller
|
|
596
599
|
scope: app
|
|
600
|
+
sensitive: false
|
|
597
601
|
generator:
|
|
598
602
|
type: literal
|
|
599
603
|
value: 'miso-controller-miso-miso-controller'
|
|
@@ -615,10 +619,35 @@ parameters:
|
|
|
615
619
|
Per-app OAuth client secret used by miso-controller for service-to-service auth (MISO_CLIENTSECRET).
|
|
616
620
|
Generated on first ensure for local bootstrap.
|
|
617
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
|
+
|
|
618
646
|
# Dataplane ↔ controller OAuth (builder/dataplane env.template MISO_CLIENTID / MISO_CLIENTSECRET).
|
|
619
647
|
- key: dataplane-client-idKeyVault
|
|
620
648
|
ownerAppKey: dataplane
|
|
621
649
|
scope: app
|
|
650
|
+
sensitive: false
|
|
622
651
|
generator:
|
|
623
652
|
type: literal
|
|
624
653
|
value: 'miso-controller-dev-dataplane'
|
|
@@ -652,18 +681,39 @@ parameters:
|
|
|
652
681
|
notes: Empty locally; set when calling Mori with API key auth.
|
|
653
682
|
|
|
654
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.
|
|
655
695
|
- key: mori-license-public-keyKeyVault
|
|
656
696
|
category: Mori
|
|
697
|
+
ownerAppKey: miso-controller
|
|
657
698
|
sensitive: true
|
|
658
699
|
valueSource: optionalInput
|
|
659
700
|
requiredOnSystemOnboarding: false
|
|
660
|
-
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.
|
|
661
709
|
generator:
|
|
662
|
-
type:
|
|
710
|
+
type: rsaKeyPair
|
|
711
|
+
pairId: mori-license-signing
|
|
712
|
+
part: public
|
|
663
713
|
ensureOn: [upInfra, resolveApp]
|
|
664
714
|
azure:
|
|
665
715
|
vaultSecretName: mori-license-public-keyKeyVault
|
|
666
|
-
notes:
|
|
716
|
+
notes: SPKI PEM public half of the Mori licence signing pair; linked to secrets-licensePrivateKeyVault.
|
|
667
717
|
|
|
668
718
|
- key: appinsights-connectionStringKeyVault
|
|
669
719
|
category: Observability
|
|
@@ -705,7 +755,7 @@ parameters:
|
|
|
705
755
|
vaultSecretName: loganalytics-workspace-id
|
|
706
756
|
notes: Azure SDK-derived Log Analytics workspace customer identifier.
|
|
707
757
|
|
|
708
|
-
- key:
|
|
758
|
+
- key: azure-openai/endpoint
|
|
709
759
|
category: Azure OpenAI
|
|
710
760
|
sensitive: false
|
|
711
761
|
valueSource: optionalInput
|
|
@@ -715,10 +765,10 @@ parameters:
|
|
|
715
765
|
type: emptyString
|
|
716
766
|
ensureOn: [resolveApp]
|
|
717
767
|
azure:
|
|
718
|
-
vaultSecretName:
|
|
719
|
-
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.
|
|
720
770
|
|
|
721
|
-
- key:
|
|
771
|
+
- key: azure-openai/apiKey
|
|
722
772
|
category: Azure OpenAI
|
|
723
773
|
sensitive: true
|
|
724
774
|
valueSource: optionalInput
|
|
@@ -728,21 +778,8 @@ parameters:
|
|
|
728
778
|
type: emptyString
|
|
729
779
|
ensureOn: [resolveApp]
|
|
730
780
|
azure:
|
|
731
|
-
vaultSecretName:
|
|
732
|
-
notes: Azure OpenAI API key produced by the
|
|
733
|
-
|
|
734
|
-
# Dataplane builder/dataplane env.template (AI/LLM); optional until OpenAI or Azure OpenAI is configured.
|
|
735
|
-
- key: secrets-openaiApiKeyVault
|
|
736
|
-
category: OpenAI
|
|
737
|
-
sensitive: true
|
|
738
|
-
valueSource: optionalInput
|
|
739
|
-
requiredOnSystemOnboarding: false
|
|
740
|
-
scope: system
|
|
741
|
-
generator:
|
|
742
|
-
type: emptyString
|
|
743
|
-
ensureOn: [resolveApp]
|
|
744
|
-
azure:
|
|
745
|
-
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.
|
|
746
783
|
|
|
747
784
|
- key: azure-openaiapi-urlKeyVault
|
|
748
785
|
scope: app
|
|
@@ -752,17 +789,13 @@ parameters:
|
|
|
752
789
|
azure:
|
|
753
790
|
notes: Empty until set; Azure OpenAI endpoint URL.
|
|
754
791
|
|
|
755
|
-
- key: secrets-azureOpenaiApiKeyVault
|
|
756
|
-
scope: app
|
|
757
|
-
generator:
|
|
758
|
-
type: emptyString
|
|
759
|
-
ensureOn: [upInfra, resolveApp]
|
|
760
|
-
azure:
|
|
761
|
-
notes: Empty until set; user-supplied Azure OpenAI API key (not auto-generated).
|
|
762
|
-
|
|
763
792
|
# Dataplane RS256 signing identity. The two rows are generated as one linked pair.
|
|
764
793
|
- key: secrets-certificatePrivateKeyVault
|
|
765
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.
|
|
766
799
|
scope: app
|
|
767
800
|
generator:
|
|
768
801
|
type: rsaKeyPair
|
|
@@ -773,6 +806,66 @@ parameters:
|
|
|
773
806
|
vaultSecretName: secrets-certificatePrivateKeyVault
|
|
774
807
|
notes: PKCS#8 PEM private key generated with the matching public key.
|
|
775
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
|
+
|
|
776
869
|
- key: secrets-certificatePublicKeyVault
|
|
777
870
|
ownerAppKey: dataplane
|
|
778
871
|
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'
|
|
1000
|
+
legacyVaultSecretNames:
|
|
1001
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
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'
|
|
864
1013
|
legacyVaultSecretNames:
|
|
1014
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
865
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
|
|
1180
|
+
scope: app
|
|
1181
|
+
generator:
|
|
1182
|
+
type: randomBytes32
|
|
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
|
|
938
1189
|
scope: app
|
|
939
1190
|
generator:
|
|
940
1191
|
type: randomBytes32
|
|
941
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]
|