@aifabrix/builder 2.37.9 → 2.39.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.
Files changed (74) hide show
  1. package/.cursor/rules/project-rules.mdc +3 -0
  2. package/README.md +19 -0
  3. package/integration/hubspot/hubspot-deploy.json +1 -5
  4. package/integration/hubspot/hubspot-system.json +0 -3
  5. package/lib/api/applications.api.js +29 -1
  6. package/lib/api/auth.api.js +14 -0
  7. package/lib/api/credentials.api.js +34 -0
  8. package/lib/api/datasources-core.api.js +16 -1
  9. package/lib/api/datasources-extended.api.js +18 -1
  10. package/lib/api/deployments.api.js +32 -0
  11. package/lib/api/environments.api.js +11 -0
  12. package/lib/api/external-systems.api.js +16 -1
  13. package/lib/api/pipeline.api.js +12 -4
  14. package/lib/api/service-users.api.js +41 -0
  15. package/lib/api/types/applications.types.js +1 -1
  16. package/lib/api/types/deployments.types.js +1 -1
  17. package/lib/api/types/pipeline.types.js +1 -1
  18. package/lib/api/types/service-users.types.js +24 -0
  19. package/lib/api/wizard.api.js +40 -1
  20. package/lib/app/deploy.js +86 -21
  21. package/lib/app/rotate-secret.js +3 -1
  22. package/lib/app/run-helpers.js +35 -2
  23. package/lib/app/show-display.js +30 -11
  24. package/lib/app/show.js +34 -8
  25. package/lib/cli/index.js +4 -0
  26. package/lib/cli/setup-app.js +40 -0
  27. package/lib/cli/setup-credential-deployment.js +72 -0
  28. package/lib/cli/setup-infra.js +3 -3
  29. package/lib/cli/setup-service-user.js +52 -0
  30. package/lib/cli/setup-utility.js +1 -25
  31. package/lib/commands/app-down.js +80 -0
  32. package/lib/commands/app-logs.js +146 -0
  33. package/lib/commands/app.js +24 -1
  34. package/lib/commands/credential-list.js +104 -0
  35. package/lib/commands/deployment-list.js +184 -0
  36. package/lib/commands/service-user.js +193 -0
  37. package/lib/commands/up-common.js +74 -5
  38. package/lib/commands/up-dataplane.js +13 -7
  39. package/lib/commands/up-miso.js +17 -24
  40. package/lib/core/templates.js +2 -2
  41. package/lib/external-system/deploy.js +79 -15
  42. package/lib/generator/builders.js +8 -27
  43. package/lib/generator/external-controller-manifest.js +5 -4
  44. package/lib/generator/index.js +16 -14
  45. package/lib/generator/split.js +1 -0
  46. package/lib/generator/wizard.js +4 -1
  47. package/lib/schema/application-schema.json +6 -14
  48. package/lib/schema/deployment-rules.yaml +121 -0
  49. package/lib/schema/external-system.schema.json +0 -16
  50. package/lib/utils/app-register-config.js +10 -12
  51. package/lib/utils/app-run-containers.js +2 -1
  52. package/lib/utils/compose-generator.js +2 -1
  53. package/lib/utils/deployment-errors.js +10 -0
  54. package/lib/utils/environment-checker.js +25 -6
  55. package/lib/utils/help-builder.js +0 -1
  56. package/lib/utils/image-version.js +209 -0
  57. package/lib/utils/schema-loader.js +1 -1
  58. package/lib/utils/variable-transformer.js +7 -33
  59. package/lib/validation/external-manifest-validator.js +1 -1
  60. package/package.json +1 -1
  61. package/templates/applications/README.md.hbs +1 -3
  62. package/templates/applications/dataplane/Dockerfile +2 -2
  63. package/templates/applications/dataplane/README.md +20 -6
  64. package/templates/applications/dataplane/env.template +31 -2
  65. package/templates/applications/dataplane/rbac.yaml +1 -1
  66. package/templates/applications/dataplane/variables.yaml +7 -4
  67. package/templates/applications/keycloak/Dockerfile +3 -3
  68. package/templates/applications/keycloak/README.md +14 -4
  69. package/templates/applications/keycloak/env.template +17 -2
  70. package/templates/applications/keycloak/variables.yaml +2 -1
  71. package/templates/applications/miso-controller/README.md +1 -3
  72. package/templates/applications/miso-controller/env.template +85 -25
  73. package/templates/applications/miso-controller/rbac.yaml +15 -0
  74. package/templates/applications/miso-controller/variables.yaml +24 -23
@@ -18,17 +18,27 @@ npm install -g @aifabrix/builder
18
18
  # Check your environment
19
19
  aifabrix doctor
20
20
 
21
- # Login to controller (change your own port)
22
- aifabrix login --method device --environment dev --controller http://localhost:3100
21
+ # Login to controller (debug mode -c http://localhost:3010 - change your own port)
22
+ aifabrix login
23
23
 
24
24
  # Register your application (gets you credentials automatically)
25
25
  aifabrix app register dataplane
26
+
27
+ # Rotate credentials if needed:
28
+ aifabrix app rotate-secret dataplane
29
+
30
+ # Run locally
31
+ aifabrix run dataplane
32
+
33
+ # Deploy to miso-controller
34
+ aifabrix deploy dataplane
35
+
26
36
  ```
27
37
 
28
38
  ### 3. Build & Run Locally
29
39
 
30
40
  ```bash
31
- # Build the Docker image
41
+ # Build the Docker image (latest)
32
42
  aifabrix build dataplane
33
43
 
34
44
  # Run locally
@@ -41,7 +51,7 @@ aifabrix run dataplane
41
51
 
42
52
  ## Testing dataplane (use DATAPLANE_TEST_GUIDE)
43
53
 
44
- **Use the builder's Dataplane Test Guide** for auth, health, wizard, external systems, and pipeline checks:
54
+ **Use the builders Dataplane Test Guide** for auth, health, wizard, external systems, and pipeline checks:
45
55
 
46
56
  - **In aifabrix-builder:** `integration/hubspot/DATAPLANE_TEST_GUIDE.md`
47
57
  - **Dataplane base URL:** `http://localhost:3111`
@@ -53,13 +63,13 @@ Keep `build.localPort` in `variables.yaml` at **3111** so it matches that guide.
53
63
  **View logs:**
54
64
 
55
65
  ```bash
56
- docker logs aifabrix-dataplane -f
66
+ docker logs aifabrix-dev06-dataplane -f
57
67
  ```
58
68
 
59
69
  **Stop:**
60
70
 
61
71
  ```bash
62
- docker stop aifabrix-dataplane
72
+ docker stop aifabrix-dev06-dataplane
63
73
  ```
64
74
 
65
75
  ### 4. Deploy to Azure
@@ -73,6 +83,7 @@ aifabrix push dataplane --registry myacr.azurecr.io --tag "v1.0.0,latest"
73
83
 
74
84
  # Deploy to miso-controller
75
85
  aifabrix deploy dataplane
86
+
76
87
  ```
77
88
 
78
89
  ---
@@ -168,6 +179,8 @@ export AIFABRIX_HOME=/custom/path
168
179
  export AIFABRIX_SECRETS=/path/to/secrets.yaml
169
180
  ```
170
181
 
182
+ **Default OAuth callback URL:** Set `DATAPLANE_WEB_SERVER_URL` (e.g. in `env.template` as `http://localhost:${PORT}`) so the dataplane can build the default OAuth2 callback URL when `redirectUri` is omitted. The callback URL is `{DATAPLANE_WEB_SERVER_URL}/auth/callback`. When you change the domain (e.g. from localhost to a production URL), update this single variable and register the same callback URL in your OAuth app (e.g. HubSpot).
183
+
171
184
  ---
172
185
 
173
186
  ## Troubleshooting
@@ -178,6 +191,7 @@ export AIFABRIX_SECRETS=/path/to/secrets.yaml
178
191
  - **"Authentication failed"** → Run `aifabrix login` again
179
192
  - **"Build fails"** → Check Docker is running and `variables.yaml` → `build.secrets` path is correct
180
193
  - **"Can't connect"** → Verify infrastructure is running and PostgreSQL is accessible
194
+ - **Wizard / API 401 after `rotate-secret`** → The wizard may write `.env` to a different path (e.g. `../../.env`). Ensure the **project root** `.env` has the new `MISO_CLIENTID` and `MISO_CLIENTSECRET` (copy from the rotate-secret output or run `make resolve`), then **restart the backend** (`make dev` or restart the process) so it loads the new credentials.
181
195
 
182
196
  **Regenerate files:**
183
197
 
@@ -6,12 +6,19 @@
6
6
  # APPLICATION ENVIRONMENT
7
7
  # =============================================================================
8
8
 
9
+ # HTTP port for the app
9
10
  PORT=3001
11
+ # development | staging | production
10
12
  ENVIRONMENT=development
13
+ # Enable debug mode
11
14
  DEBUG=false
15
+ # Logging level: DEBUG, INFO, WARNING, ERROR, CRITICAL
12
16
  LOG_LEVEL=INFO
17
+ # Log format: json or text
13
18
  LOG_FORMAT=json
19
+ # Path for log file output
14
20
  LOG_FILE_PATH=/mnt/data/logs/app.log
21
+ # If true, run without Redis/Celery (single process)
15
22
  LOCAL_MODE=false
16
23
 
17
24
  # When API_KEY is set, a matching Bearer token bypasses OAuth2 validation
@@ -19,7 +26,10 @@ API_KEY=kv://miso-controller-api-key-secretKeyVault
19
26
 
20
27
  # API Configuration
21
28
  API_V1_STR=/api/v1
22
- VERSION=1.6.0
29
+ VERSION=1.7.0
30
+ # Base URL for the dataplane web server (used for default OAuth2 callback URL when redirectUri is omitted)
31
+ DATAPLANE_WEB_SERVER_URL=kv://dataplane-web-server-urlKeyVault
32
+ DATAPLANE_INTERNAL_URL=kv://dataplane-internal-server-urlKeyVault
23
33
 
24
34
  # CORS Configuration
25
35
  ALLOWED_ORIGINS=http://localhost:*
@@ -32,6 +42,7 @@ ENCRYPTION_KEY=kv://secrets-encryptionKeyVault
32
42
  # DATABASE CONFIGURATION
33
43
  # =============================================================================
34
44
 
45
+ # Primary app database URL
35
46
  DATABASE_URL=kv://databases-dataplane-0-urlKeyVault
36
47
  DB_0_PASSWORD=kv://databases-dataplane-0-passwordKeyVault
37
48
 
@@ -59,8 +70,11 @@ REDIS_URL=kv://redis-url
59
70
  # CACHE CONFIGURATION
60
71
  # =============================================================================
61
72
 
73
+ # Enable in-memory cache
62
74
  CACHE_ENABLED=true
75
+ # TTL in seconds for CIP execution cache
63
76
  CACHE_CIP_EXECUTION_TTL=1800
77
+ # TTL in seconds for metadata filter cache
64
78
  CACHE_METADATA_FILTER_TTL=3600
65
79
 
66
80
  # =============================================================================
@@ -72,12 +86,25 @@ MISO_CLIENTID=kv://dataplane-client-idKeyVault
72
86
  MISO_CLIENTSECRET=kv://dataplane-client-secretKeyVault
73
87
 
74
88
  # Keycloak Configuration (for OAuth2 endpoints)
89
+ # Public: used by OpenAPI OAuth2 / browser (authorizationUrl, tokenUrl).
75
90
  KEYCLOAK_SERVER_URL=kv://keycloak-server-urlKeyVault
91
+ # Internal (same role as MISO_CONTROLLER_URL): future server-side Keycloak (e.g. JWKS). Not used by dataplane today.
92
+ KEYCLOAK_INTERNAL_SERVER_URL=kv://keycloak-internal-server-urlKeyVault
76
93
  KEYCLOAK_REALM=aifabrix
77
94
 
78
- # MISO Controller URL
95
+ # =============================================================================
96
+ # MISO CONTROLLER CONFIGURATION
97
+ # =============================================================================
98
+ # Public: browser redirects and CORS for client_token; set when controller is behind a different public URL.
99
+ MISO_WEB_SERVER_URL=kv://miso-controller-web-server-urlKeyVault
100
+ # Internal: server-to-controller API calls (auth, pipeline, status, RBAC).
79
101
  MISO_CONTROLLER_URL=http://${MISO_HOST}:${MISO_PORT}
80
102
 
103
+ # Pipeline env key for controller URLs: /api/v1/pipeline/{envKey}/validate and /deploy.
104
+ # Set MISO_PIPELINE_ENV_KEY=dev when controller uses dev (e.g. MISO_CLIENTID=miso-controller-dev-dataplane).
105
+ # If unset, derived from MISO_CLIENTID (e.g. dev from miso-controller-dev-dataplane).
106
+ MISO_PIPELINE_ENV_KEY=
107
+
81
108
  # =============================================================================
82
109
  # AI/LLM CONFIGURATION
83
110
  # =============================================================================
@@ -102,12 +129,14 @@ AUTH_AUDIT_ENABLED=true
102
129
 
103
130
  # ABAC Audit Configuration
104
131
  ABAC_AUDIT_ENABLED=true
132
+ # ABAC audit detail: summary | detailed
105
133
  ABAC_AUDIT_DETAIL_LEVEL=summary
106
134
  ABAC_EXPLAIN_MODE_ENABLED=false
107
135
  ABAC_PERFORMANCE_THRESHOLD_MS=1000
108
136
 
109
137
  # RBAC Audit Configuration
110
138
  RBAC_AUDIT_ENABLED=true
139
+ # RBAC audit detail: summary | detailed | explain
111
140
  RBAC_AUDIT_DETAIL_LEVEL=summary
112
141
  RBAC_EXPLAIN_MODE_ENABLED=false
113
142
 
@@ -280,4 +280,4 @@ permissions:
280
280
 
281
281
  - name: "dataplane:rbac-simulate"
282
282
  roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-developer"]
283
- description: "Simulate RBAC policy evaluation in IDE"
283
+ description: "Simulate RBAC policy evaluation in IDE"
@@ -2,9 +2,10 @@
2
2
  app:
3
3
  key: dataplane
4
4
  displayName: "AI Fabrix Dataplane"
5
- description: "Python microservice for AI processing and bulk operations. Handles document processing, external data management, and Flowise integration with MisoClient SDK authentication."
5
+ description: "AI Fabrix Dataplane is a secure, in-tenant integration and automation layer that supplies governed, normalized, and explainable enterprise data to AI agents. Using CIP as a declarative standard, it enforces RBAC and ABAC, executes integrations, and exposes trusted data via MCP and OpenAPI."
6
6
  type: webapp
7
7
  language: python # Explicitly specify Python language
8
+ version: 1.7.0
8
9
 
9
10
  # Image Configuration
10
11
  # Set tag to match your build (e.g. aifabrix build dataplane -t v1.0.0 then tag: v1.0.0)
@@ -45,11 +46,13 @@ authentication:
45
46
  requiredRoles: ["aifabrix-user"]
46
47
 
47
48
  # Build Configuration
49
+ # Dataplane builds from published image; context is project root (like miso-controller)
48
50
  build:
49
- context: ../.. # Relative to builder/dataplane/ config location (goes to app root)
50
- dockerfile: builder/dataplane/Dockerfile
51
+ context: ../.. # Docker build context (relative to builder/dataplane/)
52
+ dockerfile: builder/dataplane/Dockerfile # Dockerfile path (relative to project root)
51
53
  envOutputPath: ../../.env # Copy to repo root for local dev
52
- localPort: 3011 # Port for local development (different from Docker port)
54
+ localPort: 3011 # Port for local development (different from Docker port)
55
+ language: python # Runtime language for template selection (typescript or python)
53
56
 
54
57
  # =============================================================================
55
58
  # Portal Input Configuration (Deployment Wizard)
@@ -1,7 +1,7 @@
1
1
  # Keycloak Identity and Access Management with Custom Themes
2
- # This Dockerfile extends Keycloak 26.4 with custom themes
2
+ # This Dockerfile extends Keycloak 26.5.2 with custom themes
3
3
 
4
- FROM quay.io/keycloak/keycloak:26.4
4
+ FROM quay.io/keycloak/keycloak:26.5.2
5
5
 
6
6
  # Set working directory
7
7
  WORKDIR /opt/keycloak
@@ -34,4 +34,4 @@ EXPOSE 8080
34
34
 
35
35
  # Default Keycloak command (can be overridden in docker-compose.yaml)
36
36
  # Health checks are enabled via the build step above
37
- CMD ["start-dev"]
37
+ CMD ["start-dev"]
@@ -40,6 +40,18 @@ aifabrix run keycloak
40
40
 
41
41
  **Access your app:** <http://dev.aifabrix:8082>
42
42
 
43
+ **Token issuer (Docker + refresh):** Keycloak is configured with `KC_HOSTNAME=localhost` and `KC_HOSTNAME_PORT=${KEYCLOAK_PUBLIC_PORT}` so tokens always have issuer `http://localhost:<port>/realms/aifabrix`. This lets refresh work when users log in via localhost and the controller (in Docker) calls Keycloak at `http://keycloak:8080`.
44
+
45
+ **If you get "Invalid token issuer. Expected 'http://keycloak:8080/realms/aifabrix'" on refresh:**
46
+
47
+ 1. Set `KEYCLOAK_PUBLIC_PORT` to the port you use for Keycloak (e.g. if your token issuer shows `http://localhost:8682/realms/aifabrix`, use `8682`). In `.env` (in the directory where you run `aifabrix resolve keycloak`) add or set: `KEYCLOAK_PUBLIC_PORT=8682`.
48
+ 2. Regenerate Keycloak env and restart Keycloak:
49
+ ```bash
50
+ aifabrix resolve keycloak
51
+ docker restart $(docker ps -q -f name=keycloak)
52
+ ```
53
+ 3. Re-run `pnpm validate:config -- --test-refresh` from the repo root.
54
+
43
55
  **View logs:**
44
56
 
45
57
  ```bash
@@ -93,8 +105,7 @@ aifabrix dockerfile keycloak --force # Generate Dockerfile
93
105
  aifabrix resolve keycloak # Generate .env file
94
106
 
95
107
  # Deployment
96
- aifabrix json keycloak # Preview deployment JSON
97
- aifabrix genkey keycloak # Generate deployment key
108
+ aifabrix json keycloak # Generate deployment manifest
98
109
  aifabrix push keycloak --registry myacr.azurecr.io # Push to ACR
99
110
  aifabrix deploy keycloak --controller <url> # Deploy to Azure
100
111
 
@@ -128,7 +139,7 @@ aifabrix run keycloak --debug # Debug output
128
139
 
129
140
  ```bash
130
141
  aifabrix push keycloak --registry myacr.azurecr.io --tag v1.0.0
131
- aifabrix push keycloak --registry myacr.azurecr.io --tag "v1.0.0,latest,stable"
142
+ aifabrix push keycloak --registry myacr.azurecr.io --tag "v1.0.0,latest"
132
143
  ```
133
144
 
134
145
  ### Deploy Options
@@ -174,7 +185,6 @@ export AIFABRIX_SECRETS=/path/to/secrets.yaml
174
185
  ```bash
175
186
  aifabrix resolve keycloak --force
176
187
  aifabrix json keycloak
177
- aifabrix genkey keycloak
178
188
  ```
179
189
 
180
190
  ---
@@ -11,6 +11,23 @@ KEYCLOAK_ADMIN_PASSWORD=kv://keycloak-admin-passwordKeyVault
11
11
  KC_HOSTNAME_STRICT=false
12
12
  KC_HTTP_ENABLED=true
13
13
 
14
+ # =============================================================================
15
+ # HOSTNAME / ISSUER (Docker vs localhost)
16
+ # =============================================================================
17
+ # Flow: Client gets callback from Keycloak (public URL) → server does auth code
18
+ # exchange by calling Keycloak on the INTERNAL address (keycloak:8080). Keycloak
19
+ # must use the PUBLIC URL as issuer in all tokens so they match what the
20
+ # controller expects (KEYCLOAK_SERVER_URL).
21
+ # - Users log in via http://localhost:${KEYCLOAK_PUBLIC_PORT} (browser/CLI)
22
+ # - Server calls Keycloak at http://keycloak:8080 for token exchange and refresh
23
+ # - Controller sends Host: localhost:${KEYCLOAK_PUBLIC_PORT} so Keycloak validates issuer
24
+ # against public URL (requires KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true)
25
+ # When KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true, hostname must be a full URL
26
+ KC_HOSTNAME=http://localhost:${KEYCLOAK_PUBLIC_PORT}
27
+ KC_HOSTNAME_PORT=${KEYCLOAK_PUBLIC_PORT}
28
+ # Required for Host header to work: Keycloak resolves backchannel URL from request headers
29
+ KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true
30
+
14
31
  # =============================================================================
15
32
  # HEALTH CHECK CONFIGURATION
16
33
  # =============================================================================
@@ -30,8 +47,6 @@ KC_HTTP_MANAGEMENT_HEALTH_ENABLED=false
30
47
  # MISO Application Client Credentials (per application)
31
48
  MISO_CLIENTID=kv://keycloak-client-idKeyVault
32
49
  MISO_CLIENTSECRET=kv://keycloak-client-secretKeyVault
33
- MISO_CONTROLLER_URL=http://${MISO_HOST}:${MISO_PORT}
34
- MISO_WEB_SERVER_URL=kv://miso-controller-web-server-url
35
50
 
36
51
  # Connects to postgres service in Docker network (postgres) or localhost (local)
37
52
 
@@ -4,6 +4,7 @@ app:
4
4
  displayName: 'AI Fabrix Keycloak'
5
5
  description: 'Identity and Access Management'
6
6
  type: webapp
7
+ version: '26.5.2'
7
8
 
8
9
  # Image Configuration
9
10
  image:
@@ -12,7 +13,7 @@ image:
12
13
  registry: devflowiseacr.azurecr.io
13
14
  registryMode: acr
14
15
 
15
- # Port Configuration
16
+ # Port Configuration (base for host; host port = 8082 + developer_id*100 from ~/.aifabrix/config.yaml)
16
17
  port: 8082
17
18
 
18
19
  # Azure Requirements
@@ -93,8 +93,7 @@ aifabrix dockerfile miso-controller --force # Generate Dockerfile
93
93
  aifabrix resolve miso-controller # Generate .env file
94
94
 
95
95
  # Deployment
96
- aifabrix json miso-controller # Preview deployment JSON
97
- aifabrix genkey miso-controller # Generate deployment key
96
+ aifabrix json miso-controller # Generate deployment manifest
98
97
  aifabrix push miso-controller --registry myacr.azurecr.io # Push to ACR
99
98
  aifabrix deploy miso-controller --controller <url> # Deploy to Azure
100
99
 
@@ -348,7 +347,6 @@ Failed to getSecret postgres-adminPassword: Secret not found
348
347
  ```bash
349
348
  aifabrix resolve miso-controller --force
350
349
  aifabrix json miso-controller
351
- aifabrix genkey miso-controller
352
350
  ```
353
351
 
354
352
  ---
@@ -79,13 +79,23 @@ REDIS_ROLES_TTL=900
79
79
  REDIS_PERMISSIONS_TTL=900
80
80
 
81
81
  # =============================================================================
82
- # KEYCLOAK CONFIGURATION
82
+ # KEYCLOAK CONFIGURATION (single canonical block)
83
83
  # =============================================================================
84
- # Connects to external keycloak from aifabrix-setup
84
+ # Connects to external Keycloak from aifabrix-setup.
85
+ #
86
+ # URL semantics:
87
+ # KEYCLOAK_SERVER_URL = Public URL (browser, issuer, OAuth callbacks)
88
+ # KEYCLOAK_INTERNAL_SERVER_URL = Internal URL (server-to-Keycloak HTTP only, e.g. Docker)
89
+ #
90
+ # Usage: Env vars are used for bootstrap/onboarding only. Runtime config comes from DB
91
+ # (KeycloakConfiguration + Application url/internalUrl). Sync env->DB at startup via
92
+ # sync-application-urls-from-env.service.
93
+ #
94
+ # NOTE: Do NOT onboard Azure Entra SSO in Keycloak during onboarding (skipAzureEntraSso=true).
85
95
 
86
96
  KEYCLOAK_REALM=aifabrix
87
97
  KEYCLOAK_SERVER_URL=kv://keycloak-server-urlKeyVault
88
- KEYCLOAK_PUBLIC_SERVER_URL=kv://keycloak-public-server-urlKeyVault
98
+ KEYCLOAK_INTERNAL_SERVER_URL=kv://keycloak-internal-server-urlKeyVault
89
99
  KEYCLOAK_CLIENT_ID=miso-controller
90
100
  KEYCLOAK_CLIENT_SECRET=kv://keycloak-client-secretKeyVault
91
101
  KEYCLOAK_ADMIN_USERNAME=admin
@@ -100,12 +110,11 @@ KEYCLOAK_EVENTS_ENABLED=true
100
110
  KEYCLOAK_EVENTS_VERIFY_SIGNATURE=true
101
111
  KEYCLOAK_EVENTS_SECRET=kv://keycloak-events-secretKeyVault
102
112
 
103
- # Keycloak Startup Wait Configuration (optional)
104
- # Auto-detected in Azure (WEBSITE_SITE_NAME present) - waits 20min by default
105
- # Local environments skip the wait automatically
106
- # Override if needed:
107
- # WAIT_FOR_KEYCLOAK=true|false
108
- # KEYCLOAK_WAIT_TIMEOUT=1200
113
+ # Keycloak Startup Wait Configuration
114
+ # When true, controller waits for Keycloak before onboarding (ensures admin user creation succeeds).
115
+ # Recommended for local Docker and Azure where Keycloak and controller start together.
116
+ WAIT_FOR_KEYCLOAK=true
117
+ # KEYCLOAK_WAIT_TIMEOUT=60
109
118
 
110
119
  # =============================================================================
111
120
  # AZURE AD PROVIDER CONFIGURATION
@@ -120,9 +129,9 @@ AZURE_CLIENT_SECRET=kv://azure-client-secretKeyVault
120
129
  # =============================================================================
121
130
  # DEPLOYMENT TYPE CONFIGURATION
122
131
  # =============================================================================
123
- # Controls deployment behavior for Azure, mock Azure, or local Docker deployments
132
+ # Controls deployment behavior for Azure, mock Azure, local Docker, or database-only deployments
124
133
  #
125
- # DEPLOYMENT types: azure, azure-mock, local
134
+ # DEPLOYMENT types: azure, azure-mock, local, database
126
135
  #
127
136
  # -----------------------------------------------------------------------------
128
137
  # DEPLOYMENT=azure: Real Azure Operations (Production Mode)
@@ -151,8 +160,7 @@ AZURE_CLIENT_SECRET=kv://azure-client-secretKeyVault
151
160
  # DEPLOYMENT=local: Local Docker Deployment (Localhost Controller)
152
161
  # -----------------------------------------------------------------------------
153
162
  # - Does NOT touch Azure at all (completely skips all Azure operations)
154
- # - Deploys applications as Docker containers on localhost
155
- # - Uses docker-compose for container orchestration
163
+ # - Deploys applications as Docker containers on localhost (runs "docker run")
156
164
  # - Works with local PostgreSQL and Redis containers
157
165
  # - Fastest mode for local development (no Azure SDK overhead)
158
166
  # - No Azure SDK initialization (reduces startup time)
@@ -162,13 +170,57 @@ AZURE_CLIENT_SECRET=kv://azure-client-secretKeyVault
162
170
  # - Local development and testing of applications
163
171
  # - Testing deployment workflows with actual containers
164
172
  # - Development when Azure SDK is not needed
165
- # - Fastest startup time for development
173
+ #
174
+ # Requirements (controller must be able to run "docker" successfully):
175
+ # - Docker must be installed and running where the controller runs
176
+ # - Docker network (e.g. infra-<env>-aifabrix-network) must exist
177
+ #
178
+ # When miso-controller runs INSIDE a Docker container (e.g. aifabrix up-miso):
179
+ # - The controller has no Docker CLI or host daemon by default, so deployments
180
+ # will fail with "docker: not found" unless you either:
181
+ # (A) Mount the host Docker socket and install Docker CLI in the controller
182
+ # image (e.g. -v /var/run/docker.sock:/var/run/docker.sock and docker
183
+ # client in the image), or
184
+ # (B) Use DEPLOYMENT=database instead and start apps from the host, e.g.:
185
+ # "aifabrix up-dataplane" (controller will only update DB; you run
186
+ # dataplane/other apps via aifabrix on the host).
187
+ # - Recommended when controller is in Docker: DEPLOYMENT=database and start
188
+ # dataplane with "aifabrix up-dataplane" (see QUICK-START.md).
189
+ #
190
+ # -----------------------------------------------------------------------------
191
+ # DEPLOYMENT=database: Database-Only Mode (DB Updates Only)
192
+ # -----------------------------------------------------------------------------
193
+ # - Performs only database operations (deployment/job/application records, RBAC sync)
194
+ # - Does NOT run Docker containers (no container startup, health checks, port mapping)
195
+ # - Does NOT use Azure SDK (no Azure SDK initialization overhead)
196
+ # - Fastest mode for CI/CD pipelines that only need DB state validation
197
+ # - Use for: Testing DB workflows, validating RBAC sync, testing deployment records
198
+ #
199
+ # Example use cases:
200
+ # - CI/CD pipelines that validate deployment workflow without containers
201
+ # - Testing RBAC sync logic without Docker/Azure dependencies
202
+ # - Validating database schema changes and migrations
203
+ # - Testing deployment job creation and status updates
204
+ # - Fast validation of DB state changes
205
+ #
206
+ # What happens:
207
+ # - Creates deployment job in database
208
+ # - Updates deployment status (DEPLOYING → COMPLETED)
209
+ # - Updates application record (status, version, repository URL)
210
+ # - Syncs roles and permissions (RBAC)
211
+ # - Marks deployment as completed
212
+ # - Cleans up expired tokens
213
+ # - Invalidates role/permission caches
214
+ #
215
+ # What does NOT happen:
216
+ # - No Docker container execution
217
+ # - No Azure SDK initialization
218
+ # - No container URLs or health check URLs
166
219
  #
167
220
  # Requirements:
168
- # - Docker must be installed and running
169
- # - docker-compose must be available
170
- # - Docker network (infra-aifabrix-network) must exist
171
- # - Local PostgreSQL container for database (if required)
221
+ # - Database connection (DATABASE_URL)
222
+ # - No Docker required
223
+ # - No Azure credentials required
172
224
  #
173
225
  # -----------------------------------------------------------------------------
174
226
  # Configuration Notes
@@ -181,15 +233,17 @@ AZURE_CLIENT_SECRET=kv://azure-client-secretKeyVault
181
233
  # - Production: DEPLOYMENT=azure
182
234
  # - Staging: DEPLOYMENT=azure
183
235
  # - Local Development: DEPLOYMENT=azure-mock or DEPLOYMENT=local
184
- # - CI/CD Testing: DEPLOYMENT=azure-mock
236
+ # - CI/CD Testing: DEPLOYMENT=azure-mock or DEPLOYMENT=database
185
237
  # - Local Docker development: DEPLOYMENT=local
238
+ # - DB-only validation/testing: DEPLOYMENT=database
186
239
  #
187
240
  # When to use each mode:
188
241
  # - Need to deploy to actual Azure resources? → DEPLOYMENT=azure
189
242
  # - Need to test deployment logic without creating resources? → DEPLOYMENT=azure-mock
190
243
  # - Want to run applications locally in Docker? → DEPLOYMENT=local
244
+ # - Only need DB updates and RBAC sync (no containers/Azure)? → DEPLOYMENT=database
191
245
  #
192
- DEPLOYMENT=local
246
+ DEPLOYMENT=database
193
247
 
194
248
  # =============================================================================
195
249
  # SECURITY & ENCRYPTION
@@ -212,16 +266,13 @@ API_KEY=kv://miso-controller-api-key-secretKeyVault
212
266
  # =============================================================================
213
267
  # MISO CONTROLLER CONFIGURATION
214
268
  # =============================================================================
215
-
216
- # MISO Controller URL
217
- MISO_CONTROLLER_URL=http://${MISO_HOST}:${MISO_PORT}
218
-
219
269
  # Web Server URL (for OpenAPI documentation server URLs and Keycloak callbacks)
220
270
  # This is the PUBLIC-FACING URL that browsers/users access (e.g., http://localhost:3100)
221
271
  # Used to generate correct server URLs in OpenAPI spec and Keycloak callback URLs
222
272
  # For Docker: use localhost with mapped port (e.g., localhost:3100)
223
273
  # For production: use public domain (e.g., https://miso.example.com)
224
- MISO_WEB_SERVER_URL=http://localhost:${MISO_PUBLIC_PORT}
274
+ MISO_WEB_SERVER_URL=kv://miso-controller-web-server-urlKeyVault
275
+ MISO_CONTROLLER_URL=kv://miso-controller-internal-server-urlKeyVault
225
276
 
226
277
  # MISO Environment Configuration (miso, dev, tst, pro)
227
278
  MISO_ENVIRONMENT=miso
@@ -234,12 +285,21 @@ MISO_CLIENTSECRET=kv://miso-controller-client-secretKeyVault
234
285
  # Use wildcards for ports: http://localhost:*
235
286
  MISO_ALLOWED_ORIGINS=http://localhost:*
236
287
 
288
+ # =============================================================================
289
+ # LICENSE CONFIGURATION
290
+ # =============================================================================
291
+ # Temporary development bypass: set LICENSE_JWT=DEVELOPMENT to skip Mori validation.
292
+ # Will be replaced by JWT license validation (see plan 131-jwt_license_offline_validation).
293
+ LICENSE_JWT=DEVELOPMENT
294
+
237
295
  # =============================================================================
238
296
  # MORI SERVICE CONFIGURATION
239
297
  # =============================================================================
240
298
 
241
299
  MORI_BASE_URL=kv://mori-controller-url
242
300
  MORI_API_KEY=kv://mori-controller-api-keyKeyVault
301
+ MORI_USERNAME=kv://mori-controller-basic-usernameKeyVault
302
+ MORI_PASSWORD=kv://mori-controller-basic-passwordKeyVault
243
303
 
244
304
  # =============================================================================
245
305
  # LOGGING CONFIGURATION
@@ -352,3 +352,18 @@ permissions:
352
352
  - name: 'delegation:admin:delete'
353
353
  roles: ['aifabrix-platform-admin', 'aifabrix-security-admin']
354
354
  description: 'Administrative delete access to all delegated credentials'
355
+
356
+ # Onboarding
357
+ - name: 'onboarding:read'
358
+ roles:
359
+ [
360
+ 'aifabrix-platform-admin',
361
+ 'aifabrix-infrastructure-admin',
362
+ 'aifabrix-deployment-admin',
363
+ 'aifabrix-observer'
364
+ ]
365
+ description: 'View onboarding status and configuration'
366
+
367
+ - name: 'onboarding:config'
368
+ roles: ['aifabrix-platform-admin', 'aifabrix-infrastructure-admin']
369
+ description: 'Configure onboarding (license, Entra ID, subscription config)'
@@ -2,8 +2,9 @@
2
2
  app:
3
3
  key: miso-controller
4
4
  displayName: 'Miso Controller'
5
- description: 'AI Fabrix Miso Controller - Backend API and orchestration service'
5
+ description: 'Miso is the AI Fabrix in-tenant controller and portal layer for securely operating enterprise AI apps inside a customer’s Azure tenant. It provides Entra ID SSO, RBAC, audit logs, environment/app configuration via schemas, and safe secret handling via Key Vault references—ensuring governance, traceability, and predictable UX across portal, SDK, and CLI.'
6
6
  type: webapp
7
+ version: '1.8.0'
7
8
 
8
9
  # Image Configuration
9
10
  image:
@@ -11,7 +12,7 @@ image:
11
12
  registry: devflowiseacr.azurecr.io
12
13
  registryMode: acr
13
14
 
14
- # Port Configuration
15
+ # Port Configuration (container port; host port = 3000 + developer_id*100 from ~/.aifabrix/config.yaml)
15
16
  port: 3000
16
17
 
17
18
  # Azure Requirements
@@ -64,7 +65,7 @@ configuration:
64
65
  - name: LOG_LEVEL
65
66
  portalInput:
66
67
  field: select
67
- label: "Log Level"
68
+ label: 'Log Level'
68
69
  options:
69
70
  - debug
70
71
  - info
@@ -74,26 +75,26 @@ configuration:
74
75
  - name: ENABLE_API_DOCS
75
76
  portalInput:
76
77
  field: select
77
- label: "Enable API Documentation (Swagger/ReDoc)"
78
+ label: 'Enable API Documentation (Swagger/ReDoc)'
78
79
  options:
79
- - "true"
80
- - "false"
80
+ - 'true'
81
+ - 'false'
81
82
 
82
83
  - name: FAST_STARTUP
83
84
  portalInput:
84
85
  field: select
85
- label: "Fast Startup (skip non-critical init)"
86
+ label: 'Fast Startup (skip non-critical init)'
86
87
  options:
87
- - "true"
88
- - "false"
88
+ - 'true'
89
+ - 'false'
89
90
 
90
91
  - name: LOG_TO_FILE
91
92
  portalInput:
92
93
  field: select
93
- label: "Log to File"
94
+ label: 'Log to File'
94
95
  options:
95
- - "true"
96
- - "false"
96
+ - 'true'
97
+ - 'false'
97
98
 
98
99
  # -------------------------------------------------------------------------
99
100
  # Keycloak Events (feature flag)
@@ -101,10 +102,10 @@ configuration:
101
102
  - name: KEYCLOAK_EVENTS_ENABLED
102
103
  portalInput:
103
104
  field: select
104
- label: "Keycloak Events (sync users/groups)"
105
+ label: 'Keycloak Events (sync users/groups)'
105
106
  options:
106
- - "true"
107
- - "false"
107
+ - 'true'
108
+ - 'false'
108
109
 
109
110
  # -------------------------------------------------------------------------
110
111
  # Rate Limiting (tune for environment)
@@ -112,14 +113,14 @@ configuration:
112
113
  - name: RATE_LIMIT_WINDOW_MS
113
114
  portalInput:
114
115
  field: text
115
- label: "Rate Limit Window (milliseconds)"
116
- placeholder: "900000"
116
+ label: 'Rate Limit Window (milliseconds)'
117
+ placeholder: '900000'
117
118
 
118
119
  - name: RATE_LIMIT_MAX
119
120
  portalInput:
120
121
  field: text
121
- label: "Rate Limit Max Requests per Window"
122
- placeholder: "100"
122
+ label: 'Rate Limit Max Requests per Window'
123
+ placeholder: '100'
123
124
 
124
125
  # -------------------------------------------------------------------------
125
126
  # Redis Cache TTL (seconds) – RBAC/roles caching
@@ -127,11 +128,11 @@ configuration:
127
128
  - name: REDIS_ROLES_TTL
128
129
  portalInput:
129
130
  field: text
130
- label: "Redis Roles Cache TTL (seconds)"
131
- placeholder: "900"
131
+ label: 'Redis Roles Cache TTL (seconds)'
132
+ placeholder: '900'
132
133
 
133
134
  - name: REDIS_PERMISSIONS_TTL
134
135
  portalInput:
135
136
  field: text
136
- label: "Redis Permissions Cache TTL (seconds)"
137
- placeholder: "900"
137
+ label: 'Redis Permissions Cache TTL (seconds)'
138
+ placeholder: '900'