@aifabrix/builder 2.60.0 → 2.62.0
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/applications.api.js +22 -2
- package/lib/api/bootstrap-snapshot.api.js +115 -0
- package/lib/api/configuration.api.js +131 -0
- package/lib/api/system-secrets.api.js +72 -0
- package/lib/app/deploy.js +14 -5
- package/lib/app/run-docker-fallback.js +6 -1
- package/lib/app/run-env-compose.js +5 -6
- package/lib/app/run-helpers.js +2 -1
- package/lib/app/run-parameter-sync.js +142 -0
- package/lib/app/run.js +6 -4
- package/lib/build/docker-build-args.js +5 -2
- package/lib/build/index.js +3 -2
- package/lib/build/standard-docker-build.js +6 -2
- package/lib/channels/channel-artifact-generator.js +13 -3
- package/lib/cli/infra-guided-footers.js +10 -8
- package/lib/cli/infra-guided.js +30 -10
- package/lib/cli/setup-app.js +5 -0
- package/lib/cli/setup-environment.js +156 -0
- package/lib/cli/setup-infra-up-platform-action.js +14 -1
- package/lib/cli/setup-platform.js +2 -0
- package/lib/commands/auth-config.js +2 -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/login.js +4 -0
- package/lib/commands/repair-datasource-apply.js +5 -1
- package/lib/commands/repair-datasource-keyed-document.js +122 -0
- package/lib/commands/repair-datasource-legacy.js +94 -0
- package/lib/commands/repair-datasource-run.js +1 -0
- package/lib/commands/setup-image-refresh.js +26 -0
- package/lib/commands/setup-modes.js +8 -9
- package/lib/commands/setup-prompts-platform-mode.js +34 -0
- package/lib/commands/setup-prompts.js +2 -180
- package/lib/commands/setup.js +3 -0
- package/lib/commands/up-builder-api.js +24 -8
- package/lib/commands/up-common.js +16 -1
- package/lib/commands/up-dataplane-bootstrap.js +70 -14
- package/lib/commands/up-dataplane-credentials.js +21 -0
- package/lib/commands/up-dataplane.js +37 -18
- package/lib/commands/up-integration-server.js +112 -0
- 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 +12 -5
- package/lib/commands/wizard-core.js +5 -157
- package/lib/commands/wizard-file-saving.js +163 -0
- package/lib/core/admin-secrets-env-overlay.js +8 -3
- package/lib/core/env-platform-expand.js +5 -1
- package/lib/core/environment-access-policy.js +121 -0
- package/lib/core/environment-mode-policy.js +177 -0
- package/lib/core/local-env-overrides.js +149 -0
- package/lib/core/secrets-ensure.js +4 -2
- package/lib/core/secrets-env-content.js +17 -10
- package/lib/core/secrets-env-write.js +11 -4
- package/lib/core/secrets-load.js +4 -2
- package/lib/datasource/binary-documents-validator.js +190 -0
- package/lib/datasource/capability/capability-manifest.js +1 -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/index.js +14 -1
- package/lib/deployment/installation/infra-catalog.js +3 -0
- package/lib/deployment/installation/local-environment-stage.js +285 -0
- package/lib/deployment/installation/local-installation.js +76 -0
- package/lib/deployment/installation/stage-input.js +5 -1
- package/lib/generator/builders.js +3 -1
- package/lib/generator/index.js +3 -0
- package/lib/generator/split-variables.js +2 -2
- package/lib/lifecycle/product-model.js +4 -3
- package/lib/lifecycle/report-display.js +3 -2
- package/lib/parameters/database-adoption.js +125 -0
- package/lib/parameters/infra-parameter-catalog.js +1 -1
- package/lib/parameters/physical-database-naming.js +136 -0
- package/lib/parameters/physical-secret-name.js +194 -0
- package/lib/parameters/rsa-secret-values.js +165 -0
- 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/programmatic/run-channel-install-artifacts.js +28 -2
- package/lib/programmatic/run-channel-package.js +3 -1
- package/lib/programmatic/workspace-context.js +37 -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 +14 -2
- package/lib/schema/external-datasource.schema.json +23 -3
- package/lib/schema/infra.parameter.yaml +440 -56
- package/lib/schema/infrastructure-schema.json +213 -120
- package/lib/utils/compose-generate-docker-compose.js +9 -14
- package/lib/utils/compose-generator.js +4 -7
- package/lib/utils/compose-miso-env.js +2 -2
- package/lib/utils/compose-traefik-ingress-base.js +3 -4
- 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/declarative-url-ports.js +3 -0
- package/lib/utils/env-copy.js +11 -10
- package/lib/utils/env-environment-file-paths.js +105 -0
- package/lib/utils/environment-scoped-resources.js +48 -14
- package/lib/utils/external-system-system-test-tty.js +3 -2
- package/lib/utils/image-tags.js +2 -2
- package/lib/utils/paths-system-builder-keys.js +7 -1
- package/lib/utils/paths.js +7 -2
- package/lib/utils/platform-kv-ref.js +1 -1
- package/lib/utils/postgres-platform-bootstrap.js +35 -1
- package/lib/utils/prepare-local-data-mount.js +58 -0
- package/lib/utils/redis-env-scope.js +21 -1
- package/lib/utils/registry-auth-sources.js +154 -0
- package/lib/utils/registry-credentials.js +131 -14
- package/lib/utils/secrets-generator.js +30 -21
- package/lib/utils/secrets-helpers.js +5 -8
- package/lib/utils/secrets-kv-scope.js +127 -28
- package/lib/utils/secrets-materialize-local.js +9 -0
- package/lib/utils/secrets-missing-error.js +35 -1
- package/lib/utils/system-secret-mapping.js +125 -0
- package/lib/utils/test-log-writer.js +2 -1
- package/lib/utils/token-manager.js +14 -8
- package/lib/utils/url-public-path-prefix.js +6 -10
- 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 +6 -4
- 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 +2 -2
- package/templates/applications/dataplane/env.template +10 -12
- package/templates/applications/integration-server/application.yaml +91 -0
- package/templates/applications/integration-server/env.template +215 -0
- package/templates/applications/keycloak/application.yaml +6 -1
- package/templates/applications/mirrored-templates.json +52 -0
- package/templates/applications/miso-controller/application.yaml +116 -2
- package/templates/applications/miso-controller/env.template +62 -17
- package/templates/applications/miso-controller/rbac.yaml +17 -0
- package/templates/external-system/external-datasource.yaml.hbs +7 -1
- package/templates/marketplace/createUiDefinition.json +52 -4
- package/templates/marketplace/main.json +88 -10
- 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
|
@@ -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.
|
|
@@ -590,53 +593,92 @@ parameters:
|
|
|
590
593
|
azure:
|
|
591
594
|
notes: Not a typical Key Vault name; local optional pypi token.
|
|
592
595
|
|
|
593
|
-
#
|
|
596
|
+
# Miso Controller ↔ controller OAuth. The Controller issues both values at registration;
|
|
597
|
+
# local infrastructure must leave them empty until application resolution retrieves them.
|
|
594
598
|
- key: miso-controller-client-idKeyVault
|
|
595
599
|
ownerAppKey: miso-controller
|
|
596
600
|
scope: app
|
|
601
|
+
sensitive: false
|
|
597
602
|
generator:
|
|
598
|
-
type:
|
|
599
|
-
|
|
600
|
-
ensureOn: [upInfra, resolveApp]
|
|
603
|
+
type: emptyString
|
|
604
|
+
ensureOn: [resolveApp]
|
|
601
605
|
azure:
|
|
602
606
|
legacyVaultSecretNames:
|
|
603
607
|
- '{serviceName}-miso-clientIdKeyVault'
|
|
604
608
|
notes: >-
|
|
605
|
-
Per-app OAuth client id
|
|
609
|
+
Per-app OAuth client id issued when miso-controller is registered with Miso.
|
|
606
610
|
|
|
607
611
|
- key: miso-controller-client-secretKeyVault
|
|
608
612
|
ownerAppKey: miso-controller
|
|
609
613
|
scope: app
|
|
610
614
|
generator:
|
|
611
|
-
type:
|
|
612
|
-
ensureOn: [
|
|
615
|
+
type: emptyString
|
|
616
|
+
ensureOn: [resolveApp]
|
|
613
617
|
azure:
|
|
614
618
|
notes: >-
|
|
615
|
-
Per-app OAuth client secret
|
|
616
|
-
|
|
619
|
+
Per-app OAuth client secret issued when miso-controller is registered with Miso and used
|
|
620
|
+
for service-to-service auth (MISO_CLIENTSECRET). Never generated by local infrastructure.
|
|
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.
|
|
617
645
|
|
|
618
646
|
# Dataplane ↔ controller OAuth (builder/dataplane env.template MISO_CLIENTID / MISO_CLIENTSECRET).
|
|
647
|
+
# Plan 265.0: issued by the Controller at registration, so the catalog must not produce a
|
|
648
|
+
# value for it. The previous `literal` on the `upInfra` hook meant Builder generated an id
|
|
649
|
+
# the Controller owns — and the literal was `miso-controller-dev-dataplane`, with `dev`
|
|
650
|
+
# baked into an entry that is not dev-specific. `emptyString` on `resolveApp` is the shape
|
|
651
|
+
# `builder-api-client-idKeyVault` already uses for the same relationship.
|
|
619
652
|
- key: dataplane-client-idKeyVault
|
|
620
653
|
ownerAppKey: dataplane
|
|
621
654
|
scope: app
|
|
655
|
+
sensitive: false
|
|
622
656
|
generator:
|
|
623
|
-
type:
|
|
624
|
-
|
|
625
|
-
ensureOn: [upInfra, resolveApp]
|
|
657
|
+
type: emptyString
|
|
658
|
+
ensureOn: [resolveApp]
|
|
626
659
|
azure:
|
|
627
660
|
notes: >-
|
|
628
|
-
Per-app OAuth client id
|
|
629
|
-
|
|
630
|
-
|
|
661
|
+
Per-app OAuth client id issued when dataplane is registered with Miso. Not generated
|
|
662
|
+
locally: the Controller owns it, and a locally invented id is one the Controller has
|
|
663
|
+
never seen.
|
|
664
|
+
|
|
665
|
+
# Plan 265.0: the Controller issues this secret, so a `randomBytes32` generator on the
|
|
666
|
+
# `upInfra` hook had Builder inventing an OAuth secret the Controller owns. That invented
|
|
667
|
+
# value is what defeated the "credentials missing locally" guard and surfaced as a
|
|
668
|
+
# misleading auth error rather than a clear one. Matches
|
|
669
|
+
# `builder-api-client-secretKeyVault`.
|
|
631
670
|
- key: dataplane-client-secretKeyVault
|
|
632
671
|
ownerAppKey: dataplane
|
|
633
672
|
scope: app
|
|
634
673
|
generator:
|
|
635
|
-
type:
|
|
636
|
-
ensureOn: [
|
|
674
|
+
type: emptyString
|
|
675
|
+
ensureOn: [resolveApp]
|
|
637
676
|
azure:
|
|
638
677
|
vaultSecretName: dataplane-client-secretKeyVault
|
|
639
|
-
notes:
|
|
678
|
+
notes: >-
|
|
679
|
+
Per-app OAuth client secret issued when dataplane is registered with Miso. Never
|
|
680
|
+
generated locally; it is fetched from the Controller, which is the only party that
|
|
681
|
+
can issue one it will accept.
|
|
640
682
|
|
|
641
683
|
# Mori / telemetry is optional for an unlicensed Community installation.
|
|
642
684
|
- key: mori-controller-api-keyKeyVault
|
|
@@ -652,18 +694,46 @@ parameters:
|
|
|
652
694
|
notes: Empty locally; set when calling Mori with API key auth.
|
|
653
695
|
|
|
654
696
|
# Public, but a security-critical trust anchor. Never derive it from a pasted JWT.
|
|
697
|
+
#
|
|
698
|
+
# `sensitive: true` on a public key is deliberate -- 227.1 made Miso verify licences against a
|
|
699
|
+
# PINNED key precisely because a key travelling inside the token it verifies proves nothing, so
|
|
700
|
+
# this value must be protected from tampering even though disclosing it costs nothing.
|
|
701
|
+
#
|
|
702
|
+
# It is owned by `miso-controller` rather than left system-scoped because a system-scoped
|
|
703
|
+
# sensitive secret is readable by NO application (`forbidden-system-secret`). Measured on
|
|
704
|
+
# aifabrix-ce-16 2026-09-27: miso-controller declares MORI_LICENSE_PUBLIC_KEY in its manifest, yet
|
|
705
|
+
# the key was absent from its 70 registry rows and from its snapshot, so the installation could
|
|
706
|
+
# never have verified a licence. Ownership is what makes a trust anchor readable by the service
|
|
707
|
+
# whose trust it anchors -- the same correction already applied to secrets-policyPrivateKeyVault.
|
|
655
708
|
- key: mori-license-public-keyKeyVault
|
|
656
709
|
category: Mori
|
|
710
|
+
ownerAppKey: miso-controller
|
|
657
711
|
sensitive: true
|
|
658
712
|
valueSource: optionalInput
|
|
659
713
|
requiredOnSystemOnboarding: false
|
|
660
|
-
scope:
|
|
714
|
+
scope: app
|
|
715
|
+
# The public half of the Mori licence pair above, so the key Miso verifies with cannot drift
|
|
716
|
+
# from the key Mori signs with. Was `emptyString`: the two halves came from unrelated places
|
|
717
|
+
# and an installation could hold a perfectly valid public key belonging to a different private
|
|
718
|
+
# key, which verifies nothing and reports no error.
|
|
719
|
+
#
|
|
720
|
+
# Rotating an installation that already holds a value here means clearing BOTH halves
|
|
721
|
+
# together — the generator is get-or-create, so replacing one alone leaves a mismatched pair.
|
|
722
|
+
# Supplied, never generated. Mori owns this pair and keeps the private half; an installation
|
|
723
|
+
# that minted it would hold the private half of the key it verifies against and could sign a
|
|
724
|
+
# licence it would then accept. Builder refuses these pairs (aifabrix-builder 211.0 /
|
|
725
|
+
# 5bfeb06d); `rsaKeyPair` here made Miso mint them anyway, because catalog-resolver runs the
|
|
726
|
+
# generator unconditionally and never consults valueSource. `emptyAllowed` is what stops it:
|
|
727
|
+
# the materializer skips isEmptyByDesign rows, so Miso no longer writes this secret at all.
|
|
728
|
+
# It arrives instead as a deploy parameter -- packages.json -> main.bicep ->
|
|
729
|
+
# 08_keyvault-secrets.bicep -> the installation vault -- which is also the only writer that
|
|
730
|
+
# can hold Mori's real key rather than a locally invented one.
|
|
661
731
|
generator:
|
|
662
|
-
type:
|
|
732
|
+
type: emptyAllowed
|
|
663
733
|
ensureOn: [upInfra, resolveApp]
|
|
664
734
|
azure:
|
|
665
735
|
vaultSecretName: mori-license-public-keyKeyVault
|
|
666
|
-
notes:
|
|
736
|
+
notes: SPKI PEM public half of the Mori licence signing pair; linked to secrets-licensePrivateKeyVault.
|
|
667
737
|
|
|
668
738
|
- key: appinsights-connectionStringKeyVault
|
|
669
739
|
category: Observability
|
|
@@ -705,7 +775,7 @@ parameters:
|
|
|
705
775
|
vaultSecretName: loganalytics-workspace-id
|
|
706
776
|
notes: Azure SDK-derived Log Analytics workspace customer identifier.
|
|
707
777
|
|
|
708
|
-
- key:
|
|
778
|
+
- key: azure-openai/endpoint
|
|
709
779
|
category: Azure OpenAI
|
|
710
780
|
sensitive: false
|
|
711
781
|
valueSource: optionalInput
|
|
@@ -715,10 +785,10 @@ parameters:
|
|
|
715
785
|
type: emptyString
|
|
716
786
|
ensureOn: [resolveApp]
|
|
717
787
|
azure:
|
|
718
|
-
vaultSecretName:
|
|
719
|
-
notes: Azure OpenAI endpoint produced by the
|
|
788
|
+
vaultSecretName: dev-dataplane-azure-openai-endpoint
|
|
789
|
+
notes: Azure OpenAI endpoint produced by infrastructure at the standard dev Dataplane address.
|
|
720
790
|
|
|
721
|
-
- key:
|
|
791
|
+
- key: azure-openai/apiKey
|
|
722
792
|
category: Azure OpenAI
|
|
723
793
|
sensitive: true
|
|
724
794
|
valueSource: optionalInput
|
|
@@ -728,21 +798,8 @@ parameters:
|
|
|
728
798
|
type: emptyString
|
|
729
799
|
ensureOn: [resolveApp]
|
|
730
800
|
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.
|
|
801
|
+
vaultSecretName: dev-dataplane-azure-openai-api-key
|
|
802
|
+
notes: Azure OpenAI API key produced by infrastructure at the standard dev Dataplane address.
|
|
746
803
|
|
|
747
804
|
- key: azure-openaiapi-urlKeyVault
|
|
748
805
|
scope: app
|
|
@@ -752,17 +809,13 @@ parameters:
|
|
|
752
809
|
azure:
|
|
753
810
|
notes: Empty until set; Azure OpenAI endpoint URL.
|
|
754
811
|
|
|
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
812
|
# Dataplane RS256 signing identity. The two rows are generated as one linked pair.
|
|
764
813
|
- key: secrets-certificatePrivateKeyVault
|
|
765
814
|
ownerAppKey: dataplane
|
|
815
|
+
# Deliberately NOT shared with mori-controller. `readability-real-catalog.test.ts` asserts
|
|
816
|
+
# "denies mori signing licences with the dataplane signing key" — Mori's manifest pointing
|
|
817
|
+
# MORI_LICENSE_PRIVATE_KEY at this key is the misconfiguration, not the denial. The fix is a
|
|
818
|
+
# mori-controller-owned licence key and a manifest change, never widening this entry.
|
|
766
819
|
scope: app
|
|
767
820
|
generator:
|
|
768
821
|
type: rsaKeyPair
|
|
@@ -773,6 +826,80 @@ parameters:
|
|
|
773
826
|
vaultSecretName: secrets-certificatePrivateKeyVault
|
|
774
827
|
notes: PKCS#8 PEM private key generated with the matching public key.
|
|
775
828
|
|
|
829
|
+
# Mori's policy signing key. Present in every installation's vault but absent from this catalog,
|
|
830
|
+
# so it fell through to the `^[a-zA-Z0-9_-]+KeyVault$` catch-all — `scope: app` with no owner,
|
|
831
|
+
# which `resolveOwnershipDecision` cannot classify and the policy therefore denies to everyone.
|
|
832
|
+
#
|
|
833
|
+
# Measured on aifabrix-ce-16, 2026-09-26: the secret exists, Mori reads it today through an App
|
|
834
|
+
# Service Key Vault reference, and bootstrap omitted it. That is the same key whose absence
|
|
835
|
+
# previously failed Mori's signing health check.
|
|
836
|
+
- key: secrets-policyPrivateKeyVault
|
|
837
|
+
ownerAppKey: mori-controller
|
|
838
|
+
scope: app
|
|
839
|
+
sensitive: true
|
|
840
|
+
# Supplied, never generated. Mori owns this pair and keeps the private half; an installation
|
|
841
|
+
# that minted it would hold the private half of the key it verifies against and could sign a
|
|
842
|
+
# licence it would then accept. Builder refuses these pairs (aifabrix-builder 211.0 /
|
|
843
|
+
# 5bfeb06d); `rsaKeyPair` here made Miso mint them anyway, because catalog-resolver runs the
|
|
844
|
+
# generator unconditionally and never consults valueSource. `emptyAllowed` is what stops it:
|
|
845
|
+
# the materializer skips isEmptyByDesign rows, so Miso no longer writes this secret at all.
|
|
846
|
+
# It arrives instead as a deploy parameter -- packages.json -> main.bicep ->
|
|
847
|
+
# 08_keyvault-secrets.bicep -> the installation vault -- which is also the only writer that
|
|
848
|
+
# can hold Mori's real key rather than a locally invented one.
|
|
849
|
+
generator:
|
|
850
|
+
type: emptyAllowed
|
|
851
|
+
ensureOn: [resolveApp]
|
|
852
|
+
azure:
|
|
853
|
+
vaultSecretName: secrets-policyPrivateKeyVault
|
|
854
|
+
notes: PKCS#8 PEM private key for Mori policy signing; MORI_POLICY_KEY_ID names the pair.
|
|
855
|
+
|
|
856
|
+
# Mori's LICENCE signing key, which is not its policy signing key and not the dataplane's.
|
|
857
|
+
#
|
|
858
|
+
# `subscription-license.operations.ts` refuses to issue at all without it:
|
|
859
|
+
# if (!privateKey) throw ErrorFactory.internalServerError('License signing is unavailable')
|
|
860
|
+
# and until this entry existed there was nothing for it to read. Mori's manifest pointed
|
|
861
|
+
# MORI_LICENSE_PRIVATE_KEY at `secrets-certificatePrivateKeyVault`, which the dataplane owns, so
|
|
862
|
+
# the read was denied -- correctly. An existing test (`denies mori signing licences with the
|
|
863
|
+
# dataplane signing key`) pins that denial, so the fix is a key Mori owns, never a wider grant.
|
|
864
|
+
#
|
|
865
|
+
# `emptyString` rather than `rsaKeyPair`: the operator supplies the pair, because whoever holds
|
|
866
|
+
# this key decides which licences an installation will believe. Generating it during onboarding
|
|
867
|
+
# would make the platform mint its own trust root as a side effect of deployment. Onboarding
|
|
868
|
+
# creates the placeholder, `aifabrix env secret push` writes the real value, and create-if-absent
|
|
869
|
+
# then leaves it alone. The verifying half is `mori-license-public-keyKeyVault`, pinned to
|
|
870
|
+
# miso-controller; a pair is only useful if both halves are readable by their own service.
|
|
871
|
+
- key: secrets-licensePrivateKeyVault
|
|
872
|
+
category: Mori
|
|
873
|
+
ownerAppKey: mori-controller
|
|
874
|
+
scope: app
|
|
875
|
+
sensitive: true
|
|
876
|
+
valueSource: optionalInput
|
|
877
|
+
requiredOnSystemOnboarding: false
|
|
878
|
+
# Generated as one linked pair with mori-license-public-keyKeyVault, the same way the
|
|
879
|
+
# dataplane's signing identity is. Was `emptyString`, which meant an installation that
|
|
880
|
+
# repointed Mori at this key got nothing and `subscription-license.operations.ts` refused
|
|
881
|
+
# with "License signing is unavailable" -- so the only working configuration was the wrong
|
|
882
|
+
# one: Mori signing with the DATAPLANE's key via secrets-certificatePrivateKeyVault.
|
|
883
|
+
#
|
|
884
|
+
# Mori and the dataplane must not share a signing identity. Sharing one means the dataplane
|
|
885
|
+
# holds a key that mints licences, and the two services have completely different blast
|
|
886
|
+
# radii. Mori is the licence server; the dataplane runs customer workloads.
|
|
887
|
+
# Supplied, never generated. Mori owns this pair and keeps the private half; an installation
|
|
888
|
+
# that minted it would hold the private half of the key it verifies against and could sign a
|
|
889
|
+
# licence it would then accept. Builder refuses these pairs (aifabrix-builder 211.0 /
|
|
890
|
+
# 5bfeb06d); `rsaKeyPair` here made Miso mint them anyway, because catalog-resolver runs the
|
|
891
|
+
# generator unconditionally and never consults valueSource. `emptyAllowed` is what stops it:
|
|
892
|
+
# the materializer skips isEmptyByDesign rows, so Miso no longer writes this secret at all.
|
|
893
|
+
# It arrives instead as a deploy parameter -- packages.json -> main.bicep ->
|
|
894
|
+
# 08_keyvault-secrets.bicep -> the installation vault -- which is also the only writer that
|
|
895
|
+
# can hold Mori's real key rather than a locally invented one.
|
|
896
|
+
generator:
|
|
897
|
+
type: emptyAllowed
|
|
898
|
+
ensureOn: [resolveApp]
|
|
899
|
+
azure:
|
|
900
|
+
vaultSecretName: secrets-licensePrivateKeyVault
|
|
901
|
+
notes: PKCS#8 PEM private key for Mori licence signing; MORI_LICENSE_KEY_ID names the pair.
|
|
902
|
+
|
|
776
903
|
- key: secrets-certificatePublicKeyVault
|
|
777
904
|
ownerAppKey: dataplane
|
|
778
905
|
scope: app
|
|
@@ -825,8 +952,12 @@ parameters:
|
|
|
825
952
|
type: databaseUrl
|
|
826
953
|
ensureOn: [upInfra, resolveApp]
|
|
827
954
|
azure:
|
|
828
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-urlKeyVault'
|
|
955
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
829
956
|
legacyVaultSecretNames:
|
|
957
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
958
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
959
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
960
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
830
961
|
- '{key}'
|
|
831
962
|
- '{serviceName}-databases-0-urlKeyVault'
|
|
832
963
|
|
|
@@ -837,8 +968,12 @@ parameters:
|
|
|
837
968
|
type: databasePassword
|
|
838
969
|
ensureOn: [upInfra, resolveApp]
|
|
839
970
|
azure:
|
|
840
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-passwordKeyVault'
|
|
971
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
841
972
|
legacyVaultSecretNames:
|
|
973
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
974
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
975
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
976
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
842
977
|
- '{key}'
|
|
843
978
|
|
|
844
979
|
- key: databases-miso-controller-1-urlKeyVault
|
|
@@ -848,8 +983,12 @@ parameters:
|
|
|
848
983
|
type: databaseUrl
|
|
849
984
|
ensureOn: [upInfra, resolveApp]
|
|
850
985
|
azure:
|
|
851
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-urlKeyVault'
|
|
986
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
852
987
|
legacyVaultSecretNames:
|
|
988
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
989
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
990
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
991
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
853
992
|
- '{key}'
|
|
854
993
|
- '{serviceName}-databases-1-urlKeyVault'
|
|
855
994
|
|
|
@@ -860,9 +999,120 @@ parameters:
|
|
|
860
999
|
type: databasePassword
|
|
861
1000
|
ensureOn: [upInfra, resolveApp]
|
|
862
1001
|
azure:
|
|
863
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-passwordKeyVault'
|
|
1002
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1003
|
+
legacyVaultSecretNames:
|
|
1004
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
1005
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
1006
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1007
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
1008
|
+
- '{key}'
|
|
1009
|
+
|
|
1010
|
+
# Installed Dataplane stacks used semantic database names before the environment-scoped
|
|
1011
|
+
# convention. Keep the exact inventory here so onboarding can copy each value to its canonical
|
|
1012
|
+
# name without guessing which database slot it belongs to.
|
|
1013
|
+
- key: databases-dataplane-0-urlKeyVault
|
|
1014
|
+
ownerAppKey: dataplane
|
|
1015
|
+
scope: app
|
|
1016
|
+
generator:
|
|
1017
|
+
type: databaseUrl
|
|
1018
|
+
ensureOn: [upInfra, resolveApp]
|
|
1019
|
+
azure:
|
|
1020
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
1021
|
+
legacyVaultSecretNames:
|
|
1022
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1023
|
+
- '{key}'
|
|
1024
|
+
- dataplane-connection-string
|
|
1025
|
+
|
|
1026
|
+
- key: databases-dataplane-0-passwordKeyVault
|
|
1027
|
+
ownerAppKey: dataplane
|
|
1028
|
+
scope: app
|
|
1029
|
+
generator:
|
|
1030
|
+
type: databasePassword
|
|
1031
|
+
ensureOn: [upInfra, resolveApp]
|
|
1032
|
+
azure:
|
|
1033
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1034
|
+
legacyVaultSecretNames:
|
|
1035
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1036
|
+
- '{key}'
|
|
1037
|
+
- dataplane-password
|
|
1038
|
+
|
|
1039
|
+
- key: databases-dataplane-1-urlKeyVault
|
|
1040
|
+
ownerAppKey: dataplane
|
|
1041
|
+
scope: app
|
|
1042
|
+
generator:
|
|
1043
|
+
type: databaseUrl
|
|
1044
|
+
ensureOn: [upInfra, resolveApp]
|
|
1045
|
+
azure:
|
|
1046
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
1047
|
+
legacyVaultSecretNames:
|
|
1048
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1049
|
+
- '{key}'
|
|
1050
|
+
- dataplane-vector-connection-string
|
|
1051
|
+
|
|
1052
|
+
- key: databases-dataplane-1-passwordKeyVault
|
|
1053
|
+
ownerAppKey: dataplane
|
|
1054
|
+
scope: app
|
|
1055
|
+
generator:
|
|
1056
|
+
type: databasePassword
|
|
1057
|
+
ensureOn: [upInfra, resolveApp]
|
|
1058
|
+
azure:
|
|
1059
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1060
|
+
legacyVaultSecretNames:
|
|
1061
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1062
|
+
- '{key}'
|
|
1063
|
+
- dataplane-vector-password
|
|
1064
|
+
|
|
1065
|
+
- key: databases-dataplane-2-urlKeyVault
|
|
1066
|
+
ownerAppKey: dataplane
|
|
1067
|
+
scope: app
|
|
1068
|
+
generator:
|
|
1069
|
+
type: databaseUrl
|
|
1070
|
+
ensureOn: [upInfra, resolveApp]
|
|
1071
|
+
azure:
|
|
1072
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
1073
|
+
legacyVaultSecretNames:
|
|
1074
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1075
|
+
- '{key}'
|
|
1076
|
+
- dataplane-logs-connection-string
|
|
1077
|
+
|
|
1078
|
+
- key: databases-dataplane-2-passwordKeyVault
|
|
1079
|
+
ownerAppKey: dataplane
|
|
1080
|
+
scope: app
|
|
1081
|
+
generator:
|
|
1082
|
+
type: databasePassword
|
|
1083
|
+
ensureOn: [upInfra, resolveApp]
|
|
1084
|
+
azure:
|
|
1085
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1086
|
+
legacyVaultSecretNames:
|
|
1087
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1088
|
+
- '{key}'
|
|
1089
|
+
- dataplane-logs-password
|
|
1090
|
+
|
|
1091
|
+
- key: databases-dataplane-3-urlKeyVault
|
|
1092
|
+
ownerAppKey: dataplane
|
|
1093
|
+
scope: app
|
|
1094
|
+
generator:
|
|
1095
|
+
type: databaseUrl
|
|
1096
|
+
ensureOn: [upInfra, resolveApp]
|
|
1097
|
+
azure:
|
|
1098
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
864
1099
|
legacyVaultSecretNames:
|
|
1100
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
865
1101
|
- '{key}'
|
|
1102
|
+
- dataplane-records-connection-string
|
|
1103
|
+
|
|
1104
|
+
- key: databases-dataplane-3-passwordKeyVault
|
|
1105
|
+
ownerAppKey: dataplane
|
|
1106
|
+
scope: app
|
|
1107
|
+
generator:
|
|
1108
|
+
type: databasePassword
|
|
1109
|
+
ensureOn: [upInfra, resolveApp]
|
|
1110
|
+
azure:
|
|
1111
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
1112
|
+
legacyVaultSecretNames:
|
|
1113
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1114
|
+
- '{key}'
|
|
1115
|
+
- dataplane-records-password
|
|
866
1116
|
|
|
867
1117
|
# Per-index database secrets. Index must match requires.databases order in application.yaml.
|
|
868
1118
|
- keyPattern: '^databases-[a-z0-9-]+-\d+-urlKeyVault$'
|
|
@@ -871,8 +1121,12 @@ parameters:
|
|
|
871
1121
|
type: databaseUrl
|
|
872
1122
|
ensureOn: [upInfra, resolveApp]
|
|
873
1123
|
azure:
|
|
874
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-urlKeyVault'
|
|
1124
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-urlKeyVault'
|
|
875
1125
|
legacyVaultSecretNames:
|
|
1126
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
1127
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
1128
|
+
- '{appKey}-databases-{index}-urlKeyVault'
|
|
1129
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
876
1130
|
- '{key}'
|
|
877
1131
|
notes: The manifest key stays logical; the app-prefixed name is the physical vault key.
|
|
878
1132
|
|
|
@@ -882,12 +1136,26 @@ parameters:
|
|
|
882
1136
|
type: databasePassword
|
|
883
1137
|
ensureOn: [upInfra, resolveApp]
|
|
884
1138
|
azure:
|
|
885
|
-
vaultSecretNamePattern: '{appKey}-databases-{index}-passwordKeyVault'
|
|
1139
|
+
vaultSecretNamePattern: '{environment}-{appKey}-databases-{index}-passwordKeyVault'
|
|
886
1140
|
legacyVaultSecretNames:
|
|
1141
|
+
# Pre-environment naming: app and index only, so two environments sharing one vault
|
|
1142
|
+
# collided. Kept so installations written under it keep resolving without a vault write.
|
|
1143
|
+
- '{appKey}-databases-{index}-passwordKeyVault'
|
|
1144
|
+
# The original logical key, which is what aifabrix-ce-16 actually holds.
|
|
887
1145
|
- '{key}'
|
|
888
1146
|
|
|
1147
|
+
# Addresses, not credentials.
|
|
1148
|
+
#
|
|
1149
|
+
# These defaulted to sensitive (`sensitive` is absent, and the service reads `entry.sensitive !== false`),
|
|
1150
|
+
# so the system-secrets list API withheld the VALUE of a URL, a hostname and a virtual directory. Six
|
|
1151
|
+
# literal entries — frontdoor-url, frontdoor-host, keycloak-web-server-url,
|
|
1152
|
+
# keycloak-internal-server-url, keycloak-vdir-public, miso-controller-web-server-url and friends —
|
|
1153
|
+
# exist only to override that one key at a time, which is the hardcoding this convention removes.
|
|
1154
|
+
# An address is operator-facing by nature: hiding it makes an installation harder to diagnose and
|
|
1155
|
+
# protects nothing.
|
|
889
1156
|
# Keycloak and other *-url keys (non-database).
|
|
890
1157
|
- keyPattern: '^keycloak-.+-url$'
|
|
1158
|
+
sensitive: false
|
|
891
1159
|
scope: shared-service
|
|
892
1160
|
generator:
|
|
893
1161
|
type: emptyString
|
|
@@ -895,6 +1163,7 @@ parameters:
|
|
|
895
1163
|
|
|
896
1164
|
# App-scoped URL placeholders (filled at resolve / deploy).
|
|
897
1165
|
- keyPattern: '^[a-z0-9-]+-url$'
|
|
1166
|
+
sensitive: false
|
|
898
1167
|
scope: app
|
|
899
1168
|
generator:
|
|
900
1169
|
type: emptyString
|
|
@@ -902,6 +1171,7 @@ parameters:
|
|
|
902
1171
|
|
|
903
1172
|
# Deploy manifest maps frontDoorRouting.host templates to this secret (Azure / pipeline).
|
|
904
1173
|
- keyPattern: '^[a-z0-9-]+-frontdoor-routing-host$'
|
|
1174
|
+
sensitive: false
|
|
905
1175
|
scope: app
|
|
906
1176
|
generator:
|
|
907
1177
|
type: emptyString
|
|
@@ -910,32 +1180,146 @@ parameters:
|
|
|
910
1180
|
notes: Hostname template for Traefik / Front Door; filled at deploy.
|
|
911
1181
|
|
|
912
1182
|
- keyPattern: '^[a-z0-9-]+-vdir-public$'
|
|
1183
|
+
sensitive: false
|
|
913
1184
|
scope: app
|
|
914
1185
|
generator:
|
|
915
1186
|
type: emptyString
|
|
916
1187
|
ensureOn: [resolveApp]
|
|
917
1188
|
|
|
918
1189
|
- keyPattern: '^[a-z0-9-]+-vdir-internal$'
|
|
1190
|
+
sensitive: false
|
|
919
1191
|
scope: app
|
|
920
1192
|
generator:
|
|
921
1193
|
type: emptyString
|
|
922
1194
|
ensureOn: [resolveApp]
|
|
923
1195
|
|
|
924
1196
|
- keyPattern: '^[a-z0-9-]+-host-public$'
|
|
1197
|
+
sensitive: false
|
|
925
1198
|
scope: app
|
|
926
1199
|
generator:
|
|
927
1200
|
type: emptyString
|
|
928
1201
|
ensureOn: [resolveApp]
|
|
929
1202
|
|
|
930
1203
|
- keyPattern: '^[a-z0-9-]+-host-internal$'
|
|
1204
|
+
sensitive: false
|
|
931
1205
|
scope: app
|
|
932
1206
|
generator:
|
|
933
1207
|
type: emptyString
|
|
934
1208
|
ensureOn: [resolveApp]
|
|
935
1209
|
|
|
936
|
-
#
|
|
937
|
-
|
|
1210
|
+
# Secrets that are genuinely generated here, declared explicitly because the catch-all below no
|
|
1211
|
+
# longer invents values. Each is a shared secret with no other issuer: nothing outside this
|
|
1212
|
+
# catalog mints them, so an empty value would leave the consumer with nothing to verify against.
|
|
1213
|
+
- key: notification-event-webhook-secretKeyVault
|
|
1214
|
+
scope: app
|
|
1215
|
+
generator:
|
|
1216
|
+
type: randomBytes32
|
|
1217
|
+
ensureOn: [resolveApp]
|
|
1218
|
+
azure:
|
|
1219
|
+
vaultSecretName: notification-event-webhook-secretKeyVault
|
|
1220
|
+
notes: Shared secret signing notification webhook callbacks; generated, never supplied.
|
|
1221
|
+
|
|
1222
|
+
- key: secrets-encryptionKeyVault
|
|
1223
|
+
scope: app
|
|
1224
|
+
generator:
|
|
1225
|
+
type: randomBytes32
|
|
1226
|
+
ensureOn: [resolveApp]
|
|
1227
|
+
azure:
|
|
1228
|
+
vaultSecretName: secrets-encryptionKeyVault
|
|
1229
|
+
notes: Application-scoped encryption key; generated, never supplied.
|
|
1230
|
+
|
|
1231
|
+
- key: miso-controller-api-key-secretKeyVault
|
|
938
1232
|
scope: app
|
|
939
1233
|
generator:
|
|
940
1234
|
type: randomBytes32
|
|
941
1235
|
ensureOn: [resolveApp]
|
|
1236
|
+
azure:
|
|
1237
|
+
vaultSecretName: miso-controller-api-key-secretKeyVault
|
|
1238
|
+
notes: Generated API key for test/integration apps; generated, never supplied.
|
|
1239
|
+
|
|
1240
|
+
# `-idKeyVault` and `-nameKeyVault` are NOT secrets.
|
|
1241
|
+
#
|
|
1242
|
+
# An identifier and a name are operator-facing: a client ID, a tenant ID, a subscription ID, a
|
|
1243
|
+
# service name. They live in the same store as the secrets because they arrive the same way, but
|
|
1244
|
+
# there is nothing to withhold, and withholding them makes an installation harder to read.
|
|
1245
|
+
#
|
|
1246
|
+
# These two rows replace five literal entries that existed only to set `sensitive: false` on one
|
|
1247
|
+
# key each — `keycloak-client-idKeyVault`, `entra-client-idKeyVault`,
|
|
1248
|
+
# `azure-subscription-idKeyVault`, `azure-tenant-idKeyVault`, `azure-service-nameKeyVault`. The
|
|
1249
|
+
# convention now carries the decision, so a customer's own `myapp-tenant-idKeyVault` is readable
|
|
1250
|
+
# without an edit here.
|
|
1251
|
+
#
|
|
1252
|
+
# ORDER MATTERS: `findCatalogEntry` checks exact keys, then patterns in FILE ORDER and returns the
|
|
1253
|
+
# first match. Both suffixes also match the generic `*KeyVault` catch-all below, so they have to
|
|
1254
|
+
# stay above it or they inherit `sensitive: true` and the convention silently does nothing.
|
|
1255
|
+
- keyPattern: '^[a-zA-Z0-9_-]+-idKeyVault$'
|
|
1256
|
+
scope: app
|
|
1257
|
+
sensitive: false
|
|
1258
|
+
generator:
|
|
1259
|
+
type: emptyString
|
|
1260
|
+
ensureOn: [resolveApp]
|
|
1261
|
+
|
|
1262
|
+
- keyPattern: '^[a-zA-Z0-9_-]+-nameKeyVault$'
|
|
1263
|
+
scope: app
|
|
1264
|
+
sensitive: false
|
|
1265
|
+
generator:
|
|
1266
|
+
type: emptyString
|
|
1267
|
+
ensureOn: [resolveApp]
|
|
1268
|
+
|
|
1269
|
+
# Remaining *KeyVault secrets — created EMPTY, then supplied.
|
|
1270
|
+
#
|
|
1271
|
+
# This generated `randomBytes32`, so any `kv://<anything>KeyVault` key the catalog did not name
|
|
1272
|
+
# explicitly received 32 random bytes — 44 base64 characters — and the reference resolved to a
|
|
1273
|
+
# value that was never a credential anybody issued.
|
|
1274
|
+
#
|
|
1275
|
+
# Measured on installation aifabrix-ce-16, 2026-09-25: `secrets-policyPrivateKeyVault` is Mori's
|
|
1276
|
+
# licence-policy SIGNING KEY and held exactly that, 44 characters and not a PEM. Mori's
|
|
1277
|
+
# `signingKeysHealthCheck` parses the key rather than checking presence, so it reported
|
|
1278
|
+
# `signingKeys` down, the container exited, and the web app answered HTTP 503 on every path for two
|
|
1279
|
+
# days while App Service reported it Running. Mori's own comment had predicted this class in
|
|
1280
|
+
# writing: "the deployment builder provisioned an unknown Key Vault catalog key with a random
|
|
1281
|
+
# 44-character secret rather than failing: present, resolved, and not a private key at all".
|
|
1282
|
+
#
|
|
1283
|
+
# Empty is the correct default for a key nobody here mints. It creates the secret — so `kv://`
|
|
1284
|
+
# resolves and the reference is valid — while leaving the value visibly unset, which is a state an
|
|
1285
|
+
# operator can see and fix. A random value is indistinguishable from a real credential from the
|
|
1286
|
+
# outside, which is precisely what made it expensive.
|
|
1287
|
+
#
|
|
1288
|
+
# The catch-all stays a pattern rather than becoming a list of literals on purpose: a customer
|
|
1289
|
+
# deploying their own application declares its own `kv://` keys, and those must work without being
|
|
1290
|
+
# hardcoded here. Values arrive afterwards through the write-only system-secrets API
|
|
1291
|
+
# (`PUT /api/v1/environments/{envKey}/system-secrets/{catalogKey}`), which is what
|
|
1292
|
+
# aifabrix-builder plan 204.0 builds the CLI for.
|
|
1293
|
+
#
|
|
1294
|
+
# A secret that genuinely has no issuer but must exist gets an explicit `randomBytes32` entry
|
|
1295
|
+
# above. Adding one is the deliberate act; generation is no longer the silent default.
|
|
1296
|
+
- keyPattern: '^[a-zA-Z0-9_-]+KeyVault$'
|
|
1297
|
+
scope: app
|
|
1298
|
+
sensitive: true
|
|
1299
|
+
generator:
|
|
1300
|
+
type: emptyString
|
|
1301
|
+
ensureOn: [resolveApp]
|
|
1302
|
+
|
|
1303
|
+
# Non-secret values in the same store — the suffix carries the sensitivity.
|
|
1304
|
+
#
|
|
1305
|
+
# `*KeyVault` above means "secret": hidden by the list API, write-only through
|
|
1306
|
+
# `PUT /api/v1/environments/{envKey}/system-secrets/{catalogKey}`. `*Param` means the same storage
|
|
1307
|
+
# with nothing to hide: the list API returns the value, because `summarize()` emits `value` only
|
|
1308
|
+
# when `sensitive === false`.
|
|
1309
|
+
#
|
|
1310
|
+
# Why a pattern and not more literals: the suffix used to say nothing about sensitivity, so every
|
|
1311
|
+
# non-secret that happened to end in `KeyVault` needed its own literal row purely to set
|
|
1312
|
+
# `sensitive: false` — `keycloak-client-idKeyVault`, `entra-client-idKeyVault`,
|
|
1313
|
+
# `azure-subscription-idKeyVault`, `azure-tenant-idKeyVault`, `azure-service-nameKeyVault`. Client
|
|
1314
|
+
# IDs, tenant IDs and service names are not credentials, and hardcoding each one does not scale:
|
|
1315
|
+
# a customer deploying their own application cannot get a visible parameter without an edit here.
|
|
1316
|
+
#
|
|
1317
|
+
# With the convention, visibility is a naming decision the application author makes and a reader
|
|
1318
|
+
# can see: name it `…Param` to be readable, `…KeyVault` to be secret. Changing your mind is a
|
|
1319
|
+
# rename, not a catalog change. Both create the entry EMPTY and are supplied afterwards.
|
|
1320
|
+
- keyPattern: '^[a-zA-Z0-9_-]+Param$'
|
|
1321
|
+
scope: app
|
|
1322
|
+
sensitive: false
|
|
1323
|
+
generator:
|
|
1324
|
+
type: emptyString
|
|
1325
|
+
ensureOn: [resolveApp]
|