-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplatform-admin-components.yml
More file actions
1397 lines (1393 loc) · 50.9 KB
/
Copy pathplatform-admin-components.yml
File metadata and controls
1397 lines (1393 loc) · 50.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
openapi: 3.0.4
info:
title: Platform Admin API Components
version: 0.1.0
description: >
Entity schemas, enums, value objects, and path parameters for the
Platform Admin API. These components back the application-tenant control
surface, tenant lifecycle, self-service signup, tenant federation, and owner
onboarding operations. Secret values are write-only on the way in and are
represented on the way out only by opaque reference fields (for example
`clientSecretRef`); plaintext secrets never appear in any response schema.
paths: {}
components:
parameters:
TenantId:
name: tenantId
in: path
required: true
description: Identifier of the tenant the operation targets.
schema:
type: string
example: 7b3c2d9e-1f4a-4c8b-9e2d-5a6f7c8b9d01
Domain:
name: domain
in: path
required: true
description: Fully qualified host attached to the tenant, lowercased and without scheme or port.
schema:
type: string
example: wallet.acme.example
PublicEndpointServiceType:
name: serviceType
in: path
required: true
description: Protocol surface the public-endpoint binding describes.
schema:
$ref: '#/components/schemas/TenantPublicEndpointServiceType'
example: OID4VCI_ISSUER
SignupRequestId:
name: signupRequestId
in: path
required: true
description: Identifier of the self-service signup request.
schema:
type: string
example: signup-9f12a7c4
IdpId:
name: idpId
in: path
required: true
description: Identifier of the tenant identity provider.
schema:
type: string
example: idp-acme-corp
schemas:
# =====================================================================
# Application tenant: bootstrap/status, license, secret backend,
# onboarding policy + evaluated availability
# =====================================================================
ApplicationTenantStatus:
type: object
description: >
Runtime state of the application tenant. The application tenant is always
reachable through the platform's own hosted identity provider, so operators
can sign in even before any customer tenant exists.
required: [tenantId, status, hostedAs, canRegisterFirstRealTenant]
properties:
tenantId:
type: string
description: Identifier of the application tenant.
status:
$ref: '#/components/schemas/ApplicationTenantStatus_Status'
hostedAs:
$ref: '#/components/schemas/HostedAsStatus'
canRegisterFirstRealTenant:
type: boolean
description: True when the application tenant is ready to register the first customer tenant.
example:
tenantId: application
status: ACTIVE
hostedAs:
required: true
available: true
issuerUrl: https://auth.platform.example
canRegisterFirstRealTenant: true
ApplicationTenantStatus_Status:
type: string
description: Lifecycle state of the application tenant.
enum: [ACTIVE, SUSPENDED, PENDING_VERIFICATION]
example: ACTIVE
HostedAsStatus:
type: object
description: >
Readiness of the platform-hosted authorization server that fronts the
application tenant. `required` is a system invariant and is always `true`.
required: [required, available]
properties:
required:
type: boolean
description: Always `true`. The hosted authorization server is a system requirement.
enum: [true]
available:
type: boolean
description: True when the hosted authorization server is reachable and serving metadata.
issuerUrl:
type: string
format: uri
nullable: true
description: Issuer URL of the hosted authorization server when available.
example:
required: true
available: true
issuerUrl: https://auth.platform.example
LicenseStatusProjection:
type: object
description: >
Sanitized projection of the effective license. It exposes lifecycle status,
per-product summaries, and expiry signals; it never carries underlying
license material, decoded claims, entitlement keys, certificate chains,
or key material.
required: [status]
properties:
status:
type: string
description: Effective lifecycle status of the license.
enum: [ACTIVE, GRACE, RECOVERY, MISSING, INVALID, EXPIRED, BLOCKED]
productSummaries:
type: array
items:
$ref: '#/components/schemas/ProductLicenseSummary'
default: []
description: One summary per licensed product.
quotaProjections:
type: array
items:
$ref: '#/components/schemas/QuotaProjection'
default: []
description: Per-quota-key value projections (limit + used) for capacity meters.
customerId:
type: string
nullable: true
description: Customer identifier from the license claims, when present.
installationId:
type: string
nullable: true
description: Installation identifier the license is bound to, when present.
issuer:
type: string
nullable: true
description: Display name or identifier of the license issuer, when present.
signingCertificateFingerprint:
type: string
nullable: true
description: Hex-encoded SHA-256 fingerprint of the leaf certificate that signed the license.
expiresAt:
type: string
format: date-time
nullable: true
description: Expiry instant of the license claims, when present.
daysToExpiry:
type: integer
format: int64
nullable: true
description: Whole days until expiry, rounded up, when an expiry is present.
recoveryMode:
type: boolean
default: false
description: True when the deployment runs in recovery mode after repeated verification failures.
graceMode:
type: boolean
default: false
description: True when the license is expired but still inside the configured grace window.
warnings:
type: array
items:
type: string
default: []
description: Human-readable warnings about the license state.
example:
status: ACTIVE
productSummaries:
- product: vdx
edition: enterprise
modules: [tenant, party, oid4vci]
quotaKeys: [max-root-tenants, max-total-tenants]
quotaProjections:
- quotaKey: max-root-tenants
limit: 10
used: 4
window: null
atCap: false
customerId: cust-acme-001
installationId: 11111111-1111-4111-8111-111111111111
issuer: Platform Licensing
signingCertificateFingerprint: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
expiresAt: '2027-06-30T23:59:59Z'
daysToExpiry: 386
recoveryMode: false
graceMode: false
warnings: []
ProductLicenseSummary:
type: object
description: Per-product license summary - product, edition, licensed module names, quota key names, and quota value projections.
required: [product, edition]
properties:
product:
type: string
description: Licensed product identifier.
edition:
type: string
description: Licensed edition of the product.
modules:
type: array
items:
type: string
default: []
description: Names of the licensed modules. Module entitlement details are not exposed.
quotaKeys:
type: array
items:
type: string
default: []
description: Names of the quota keys the license defines; value projections are carried in quotaProjections.
quotaProjections:
type: array
items:
$ref: '#/components/schemas/QuotaProjection'
default: []
description: Per-product quota value projections (limit + used).
example:
product: vdx
edition: enterprise
modules: [tenant, party, oid4vci]
quotaKeys: [max-root-tenants, max-total-tenants]
QuotaProjection:
type: object
description: >
A single license quota with its hard limit and current usage. Unlike the
key-name-only `quotaKeys` list, this carries concrete VALUES so the admin
console can render capacity meters and fail-closed disable Create at cap.
required: [quotaKey, limit, used]
properties:
quotaKey:
type: string
description: The license quota key this projection reports (e.g. max-as-instances).
limit:
type: integer
format: int64
description: Hard cap the license grants for this quota key.
used:
type: integer
format: int64
description: Current consumption counted against the limit.
window:
type: string
nullable: true
description: Metering window for METERED quotas (e.g. P1M); null for CARDINALITY quotas.
atCap:
type: boolean
default: false
description: True when used has reached or exceeded limit.
example:
quotaKey: max-as-instances
limit: 5
used: 3
window: null
atCap: false
CatalogFeature:
type: object
description: >
A catalogued feature primitive: its stable namespaced+versioned key, its
typed value kind (null = boolean), a human description, and the products
that include it. Mirrors the backend FeatureRegistry entry.
required: [key, description, products]
properties:
key:
type: string
description: Stable namespaced+versioned feature key (e.g. semantic-modeling.v1).
valueType:
type: string
enum: [CARDINALITY, METERED]
nullable: true
description: Quota kind when the feature carries a numeric value; null for a boolean feature.
description:
type: string
description: Human-readable description of what the feature unlocks.
products:
type: array
items:
type: string
default: []
description: Product identifiers whose editions may include this feature.
example:
key: semantic-modeling.v1
valueType: null
description: Semantic attribute modeling and catalog authoring.
products: [vdx]
FeatureCatalog:
type: object
description: The full data-driven feature catalog assembled from the EDK and VDX slices.
required: [features]
properties:
features:
type: array
items:
$ref: '#/components/schemas/CatalogFeature'
default: []
example:
features:
- key: semantic-modeling.v1
valueType: null
description: Semantic attribute modeling and catalog authoring.
products: [vdx]
- key: tenant.instances.v1
valueType: CARDINALITY
description: Per-tenant protocol-surface instance allowance.
products: [vdx, edk]
ApplicationSecretProviderType:
type: string
description: >
Application-scope secret provider type discriminator. `vault`, `azure`, and `aws`
are writable providers. `kubernetes-mount` is read-only. The `env` provider is the
implicit read-only configuration floor and is never selected through this surface.
enum:
- vault
- azure
- aws
- kubernetes-mount
example: vault
ApplicationSecretPartitionStrategy:
type: string
description: >
How application, tenant, and instance addresses are sharded into a backend-native
address. When omitted on a write, the per-type default applies.
enum:
- TENANT_PATH_INSTANCE_PATH
- TENANT_LABEL_INSTANCE_PREFIX
- DEDICATED_BACKEND
- GLOBAL
ApplicationSecretReference:
type: object
description: Reference to secret material resolved by the configuration layer at runtime.
required: [ref]
properties:
ref:
type: string
description: Resolvable secret reference (`${secret:<logical-key>[:<key>]}` or `${env:NAME}`). Plaintext secret material is rejected.
example: ${secret:application/vault/token}
backendId:
type: string
nullable: true
description: Backend that owns the reference, when known.
example: platform-vault
createdByPlatformConfig:
type: boolean
default: false
description: True when the platform-config API created the reference and may delete it on clear or replace.
ApplicationAzureCredentialMode:
type: string
description: How the application provider authenticates to Azure.
enum:
- SERVICE_CLIENT_SECRET
- SERVICE_CLIENT_CERTIFICATE
- USER_INTERACTIVE_BROWSER
- USER_USERNAME_PASSWORD
ApplicationAzureSecretCredentialOpts:
type: object
description: Client-secret authentication.
required: [clientId, clientSecret]
properties:
clientId:
type: string
clientSecret:
type: string
writeOnly: true
description: Resolvable reference to the client secret. A plaintext secret is rejected.
ApplicationAzureCertificateCredentialOpts:
type: object
description: Client-certificate authentication.
required: [clientId, pemCertificatePath]
properties:
clientId:
type: string
pemCertificatePath:
type: string
description: Path to the PEM certificate available to the deployment.
ApplicationAzureInteractiveBrowserCredentialOpts:
type: object
description: Interactive-browser authentication.
required: [clientId, redirectUrl]
properties:
clientId:
type: string
redirectUrl:
type: string
format: uri
ApplicationAzureUsernamePasswordCredentialOpts:
type: object
description: Username/password authentication.
required: [clientId, userName, password]
properties:
clientId:
type: string
userName:
type: string
password:
type: string
writeOnly: true
description: Resolvable reference to the password. A plaintext value is rejected.
ApplicationAzureCredentialOpts:
type: object
description: Azure authentication options. Provide exactly the option block that matches `credentialMode`.
required: [credentialMode]
properties:
credentialMode:
$ref: '#/components/schemas/ApplicationAzureCredentialMode'
secretCredentialOpts:
$ref: '#/components/schemas/ApplicationAzureSecretCredentialOpts'
certificateCredentialOpts:
$ref: '#/components/schemas/ApplicationAzureCertificateCredentialOpts'
interactiveBrowserCredentialOpts:
$ref: '#/components/schemas/ApplicationAzureInteractiveBrowserCredentialOpts'
usernamePasswordCredentialOpts:
$ref: '#/components/schemas/ApplicationAzureUsernamePasswordCredentialOpts'
ApplicationAwsCredentialMode:
type: string
description: How the application provider authenticates to AWS.
enum: [ACCESS_KEY, PROFILE, CONTAINER, INSTANCE]
ApplicationAwsAccessKeyCredentialOpts:
type: object
description: Static access-key authentication.
required: [accessKeyId, secretAccessKey]
properties:
accessKeyId:
type: string
secretAccessKey:
type: string
writeOnly: true
description: Resolvable reference to the secret access key. A plaintext secret is rejected.
sessionToken:
type: string
writeOnly: true
nullable: true
description: Optional reference to a temporary session token.
ApplicationAwsProfileCredentialOpts:
type: object
description: Named shared-config profile authentication.
required: [profileName]
properties:
profileName:
type: string
ApplicationAwsCredentialOpts:
type: object
description: >
AWS authentication options. Provide the option block that matches `credentialMode`;
`CONTAINER` and `INSTANCE` source credentials from the runtime environment and need no block.
required: [credentialMode]
properties:
credentialMode:
$ref: '#/components/schemas/ApplicationAwsCredentialMode'
accessKeyCredentialOpts:
$ref: '#/components/schemas/ApplicationAwsAccessKeyCredentialOpts'
profileCredentialOpts:
$ref: '#/components/schemas/ApplicationAwsProfileCredentialOpts'
ApplicationSecretProviderStatus:
type: object
description: >
Selected application secret provider, identified by non-secret metadata. Writes route to the
selected provider and reads cascade through it; plaintext secrets never appear here.
required: [configured]
properties:
configured:
type: boolean
description: True when a secret provider has been selected.
type:
type: string
allOf:
- $ref: '#/components/schemas/ApplicationSecretProviderType'
nullable: true
description: Selected secret provider type, when one is configured.
partitionStrategy:
type: string
allOf:
- $ref: '#/components/schemas/ApplicationSecretPartitionStrategy'
nullable: true
description: Effective address sharding strategy, when one is configured.
instanceId:
type: string
nullable: true
description: Instance id folded into address sharding, when configured.
credentialMode:
type: string
nullable: true
description: Non-secret credential mode label for providers that use external credentials.
example:
configured: true
type: vault
partitionStrategy: TENANT_PATH_INSTANCE_PATH
instanceId: null
credentialMode: null
ApplicationSetSecretProviderRequestCommon:
type: object
required: [type]
properties:
type:
$ref: '#/components/schemas/ApplicationSecretProviderType'
partitionStrategy:
allOf:
- $ref: '#/components/schemas/ApplicationSecretPartitionStrategy'
description: Address sharding strategy. Omit to apply the per-type default.
instanceId:
type: string
description: Optional instance id folded into the address shard.
ApplicationSetVaultSecretProviderRequest:
description: Select and configure a HashiCorp Vault or compatible application secret provider.
allOf:
- $ref: '#/components/schemas/ApplicationSetSecretProviderRequestCommon'
- type: object
properties:
type:
type: string
enum: [vault]
address:
type: string
format: uri
description: Base URL of the Vault server.
mount:
type: string
description: KV mount path to read and write under.
credentialRef:
allOf:
- $ref: '#/components/schemas/ApplicationSecretReference'
description: Reference to the Vault token or auth secret. Plaintext secret material is rejected.
example:
type: vault
partitionStrategy: TENANT_PATH_INSTANCE_PATH
address: https://vault.platform.internal
mount: secret
credentialRef:
ref: ${env:PLATFORM_VAULT_TOKEN}
ApplicationSetAzureSecretProviderRequest:
description: Select and configure an Azure Key Vault application secret provider.
allOf:
- $ref: '#/components/schemas/ApplicationSetSecretProviderRequestCommon'
- type: object
required: [keyvaultUrl, azureTenantId, credentialOpts]
properties:
type:
type: string
enum: [azure]
keyvaultUrl:
type: string
format: uri
description: Base URL of the Azure Key Vault instance.
azureTenantId:
type: string
description: Microsoft Entra directory tenant ID the vault belongs to.
applicationId:
type: string
description: Optional application id folded into this provider's configuration.
credentialOpts:
$ref: '#/components/schemas/ApplicationAzureCredentialOpts'
example:
type: azure
keyvaultUrl: https://platform-secrets.vault.azure.net/
azureTenantId: 72f988bf-86f1-41af-91ab-2d7cd011db47
credentialOpts:
credentialMode: SERVICE_CLIENT_SECRET
secretCredentialOpts:
clientId: 11112222-3333-4444-5555-666677778888
clientSecret: ${env:PLATFORM_AZURE_SECRETS_CLIENT_SECRET}
ApplicationSetAwsSecretProviderRequest:
description: Select and configure an AWS Secrets Manager application secret provider.
allOf:
- $ref: '#/components/schemas/ApplicationSetSecretProviderRequestCommon'
- type: object
required: [region, credentialOpts]
properties:
type:
type: string
enum: [aws]
region:
type: string
description: AWS region the secrets live in.
applicationId:
type: string
description: Optional application id folded into this provider's configuration.
credentialOpts:
$ref: '#/components/schemas/ApplicationAwsCredentialOpts'
example:
type: aws
region: eu-west-1
credentialOpts:
credentialMode: ACCESS_KEY
accessKeyCredentialOpts:
accessKeyId: AKIAEXAMPLE
secretAccessKey: ${env:PLATFORM_AWS_SECRETS_SECRET}
ApplicationSetKubernetesMountSecretProviderRequest:
description: >
Select a Kubernetes secret-mount application provider. The provider is read-only; no credentials
are accepted and secret values cannot be written through this surface.
allOf:
- $ref: '#/components/schemas/ApplicationSetSecretProviderRequestCommon'
- type: object
properties:
type:
type: string
enum: [kubernetes-mount]
mountPath:
type: string
description: Filesystem path the secrets are projected to.
example:
type: kubernetes-mount
mountPath: /var/run/secrets/platform
ApplicationSecretProviderSelection:
description: >
Select and configure the application secret provider. The concrete shape is selected by `type`.
Credentials are supplied as references and are never returned.
oneOf:
- $ref: '#/components/schemas/ApplicationSetVaultSecretProviderRequest'
- $ref: '#/components/schemas/ApplicationSetAzureSecretProviderRequest'
- $ref: '#/components/schemas/ApplicationSetAwsSecretProviderRequest'
- $ref: '#/components/schemas/ApplicationSetKubernetesMountSecretProviderRequest'
discriminator:
propertyName: type
mapping:
vault: '#/components/schemas/ApplicationSetVaultSecretProviderRequest'
azure: '#/components/schemas/ApplicationSetAzureSecretProviderRequest'
aws: '#/components/schemas/ApplicationSetAwsSecretProviderRequest'
kubernetes-mount: '#/components/schemas/ApplicationSetKubernetesMountSecretProviderRequest'
OnboardingPolicy:
type: object
description: >
Onboarding policy toggles. Each toggle constrains, within what the license
allows, which onboarding flows are accepted.
required:
- rootTenantCreationEnabled
- adminInviteEnabled
- selfSignupEnabled
- subtenantSignupEnabled
- requireApprovalForSelfSignup
properties:
rootTenantCreationEnabled:
type: boolean
description: True when operators may register root tenants.
adminInviteEnabled:
type: boolean
description: True when operator-driven tenant invitations are accepted.
selfSignupEnabled:
type: boolean
description: True when public self-service signup is accepted.
subtenantSignupEnabled:
type: boolean
description: True when self-service signup under a parent tenant is accepted.
requireApprovalForSelfSignup:
type: boolean
description: True when an operator must approve a self-service signup after email verification.
updatedAt:
type: string
format: date-time
nullable: true
description: Timestamp of the last policy change, when the policy has been set.
example:
rootTenantCreationEnabled: true
adminInviteEnabled: true
selfSignupEnabled: true
subtenantSignupEnabled: false
requireApprovalForSelfSignup: true
updatedAt: '2026-06-08T09:15:00Z'
OnboardingAvailability:
type: object
description: >
Evaluated availability matrix. It composes license features (deny authority),
config toggles (deny authority within what the license allows), and runtime
readiness (email transport, secret backend, application tenant). Reason
strings follow a stable `<source>_<reason-id>` convention, for example
`license_missing_self_signup` or `config_disabled_self_signup`.
required: [applicationTenant, rootTenantCreation, adminInvite, selfSignup, subtenants, email, password, secretBackend]
properties:
applicationTenant:
$ref: '#/components/schemas/AvailabilityApplicationTenant'
rootTenantCreation:
$ref: '#/components/schemas/AvailabilityDecision'
adminInvite:
$ref: '#/components/schemas/AvailabilityDecision'
selfSignup:
$ref: '#/components/schemas/AvailabilityDecision'
subtenants:
$ref: '#/components/schemas/AvailabilityDecision'
email:
$ref: '#/components/schemas/AvailabilityEmail'
password:
$ref: '#/components/schemas/AvailabilityPassword'
secretBackend:
$ref: '#/components/schemas/AvailabilitySecretBackend'
example:
applicationTenant:
enabled: true
hostedAsAvailable: true
rootTenantCreation:
enabled: true
reason: null
adminInvite:
enabled: true
reason: null
selfSignup:
enabled: false
reason: config_disabled_self_signup
subtenants:
enabled: true
reason: null
email:
configured: true
healthy: true
password:
configured: false
healthy: false
secretBackend:
configured: true
AvailabilityApplicationTenant:
type: object
description: Application-tenant readiness inputs to the availability evaluation.
required: [enabled, hostedAsAvailable]
properties:
enabled:
type: boolean
description: True when the application tenant is active.
hostedAsAvailable:
type: boolean
description: True when the hosted authorization server is reachable.
example:
enabled: true
hostedAsAvailable: true
AvailabilityDecision:
type: object
description: Evaluated decision for a single onboarding flow, with an optional stable reason string.
required: [enabled]
properties:
enabled:
type: boolean
description: True when the flow is currently available.
reason:
type: string
nullable: true
description: Stable `<source>_<reason-id>` reason when the flow is unavailable.
example:
enabled: false
reason: license_missing_self_signup
AvailabilityEmail:
type: object
description: Email transport readiness inputs to the availability evaluation.
required: [configured, healthy]
properties:
configured:
type: boolean
description: True when an email transport is configured.
healthy:
type: boolean
description: True when the configured email transport passes its readiness probe.
example:
configured: true
healthy: true
AvailabilityPassword:
type: object
description: Owner/admin password-delivery readiness inputs to the availability evaluation.
required: [configured, healthy]
properties:
configured:
type: boolean
description: True when generated/operator password delivery is backed by a credential writer.
healthy:
type: boolean
description: True when the configured credential writer passes its readiness probe.
example:
configured: false
healthy: false
AvailabilitySecretBackend:
type: object
description: Secret-backend readiness input to the availability evaluation.
required: [configured]
properties:
configured:
type: boolean
description: True when a secret backend is configured.
example:
configured: true
# =====================================================================
# Tenants and self-service signup
# =====================================================================
Tenant:
type: object
description: A tenant in the platform control surface, including hierarchy and audit fields.
required: [id, tenantType, name, slug, status, system, createdAt, updatedAt]
properties:
id:
type: string
description: Tenant identifier.
tenantType:
type: string
description: Open tenant type label.
name:
type: string
description: Human-readable tenant name.
description:
type: string
nullable: true
description: Optional tenant description.
slug:
type: string
description: Globally unique URL-safe slug, used as the platform subdomain label and resolver path segment.
parentTenantId:
type: string
nullable: true
description: Parent tenant identifier, or null for root tenants.
status:
$ref: '#/components/schemas/TenantStatus'
system:
type: boolean
description: True for system tenants, which are excluded from default listings and slug-based resolution.
ownerPartyId:
type: string
format: uuid
nullable: true
description: Party identifier of the tenant owner, when assigned.
ownerEmail:
type: string
format: email
nullable: true
description: Email of the tenant owner captured at registration, when assigned. Human-readable owner contact for management surfaces.
ownerDisplayName:
type: string
nullable: true
description: Display name of the tenant owner captured at registration, when assigned.
createdAt:
type: string
format: date-time
description: Creation timestamp.
createdById:
type: string
format: uuid
nullable: true
description: Identifier of the principal that created the tenant.
updatedAt:
type: string
format: date-time
description: Last update timestamp.
updatedById:
type: string
format: uuid
nullable: true
description: Identifier of the principal that last updated the tenant.
deletedAt:
type: string
format: date-time
nullable: true
description: Soft-delete timestamp, when deleted.
deletedById:
type: string
format: uuid
nullable: true
description: Identifier of the principal that deleted the tenant.
example:
id: 7b3c2d9e-1f4a-4c8b-9e2d-5a6f7c8b9d01
tenantType: organization
name: Acme Corporation
description: Acme issuing and verification tenant
slug: acme
parentTenantId: null
status: ACTIVE
system: false
ownerPartyId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b
createdAt: '2026-06-08T09:00:00Z'
createdById: null
updatedAt: '2026-06-08T09:00:00Z'
updatedById: null
deletedAt: null
deletedById: null
TenantStatus:
type: string
description: Lifecycle status of a tenant.
enum: [ACTIVE, SUSPENDED, PENDING_VERIFICATION]
example: ACTIVE
TenantDomain:
type: object
description: Association between a tenant and a fully qualified host that resolves to it.
required: [id, tenantId, domain, kind, isPrimary, createdAt, updatedAt]
properties:
id:
type: string
description: Domain row identifier.
tenantId:
type: string
description: Tenant the domain belongs to.
domain:
type: string
description: Lowercased host, stored without scheme or port.
kind:
$ref: '#/components/schemas/TenantDomainKind'
isPrimary:
type: boolean
description: True when this is the canonical issuer host the authorization-server metadata renders.
verifiedAt:
type: string
format: date-time
nullable: true
description: Verification timestamp for custom domains, when verified.
verificationToken:
type: string
nullable: true
writeOnly: true
description: One-time DNS challenge token. Never returned in responses.
createdAt:
type: string
format: date-time
description: Creation timestamp.
updatedAt:
type: string
format: date-time
description: Last update timestamp.
example:
id: dom-acme-platform
tenantId: 7b3c2d9e-1f4a-4c8b-9e2d-5a6f7c8b9d01
domain: acme.wallet.platform.example
kind: PLATFORM_SUBDOMAIN
isPrimary: true
verifiedAt: '2026-06-08T09:00:00Z'
createdAt: '2026-06-08T09:00:00Z'
updatedAt: '2026-06-08T09:00:00Z'
TenantDomainKind:
type: string
description: >
Domain flavour. `PLATFORM_SUBDOMAIN` is the platform-owned `<slug>.<base>`
host, auto-created and verified at registration. `CUSTOM_DOMAIN` is a host
the customer brings; it is inserted unverified.
enum: [PLATFORM_SUBDOMAIN, CUSTOM_DOMAIN]
example: PLATFORM_SUBDOMAIN
TenantPublicEndpoint:
type: object
description: >
Public endpoint binding for a tenant-owned protocol surface. Rows describe
the externally reachable host and path that protocol metadata and dispatch
use for OID4VCI, OID4VP, and OAuth2/OIDC surfaces.
required: [id, tenantId, serviceType, enabled, primaryEndpoint, createdAt, updatedAt]
properties:
id:
type: string
description: Public-endpoint row identifier.
tenantId:
type: string
description: Tenant the binding belongs to.
serviceType:
$ref: '#/components/schemas/TenantPublicEndpointServiceType'
instanceId:
type: string
nullable: true
description: >
Software instance this binding routes to. Null is the single default
binding for the tenant and service type; a non-null value lets a tenant
own several concurrent public endpoints for the same service type, one
per instance.
host:
type: string
nullable: true
description: Lowercased host without scheme or port. Null uses the runtime host or default base.
pathPrefix:
type: string
nullable: true
description: Protocol route prefix, for example `/acme/oid4vci`.
wellKnownPath:
type: string
nullable: true
description: Well-known route, for example `/.well-known/openid-credential-issuer/acme`.
enabled:
type: boolean
description: True when the binding is active.
primaryEndpoint:
type: boolean
description: True when this is the primary binding for the tenant and service type.
createdAt:
type: string
format: date-time
description: Creation timestamp.
updatedAt:
type: string
format: date-time
description: Last update timestamp.
example:
id: pep-acme-issuer
tenantId: 7b3c2d9e-1f4a-4c8b-9e2d-5a6f7c8b9d01
serviceType: OID4VCI_ISSUER
instanceId: null
host: acme.wallet.platform.example
pathPrefix: /acme/oid4vci
wellKnownPath: /.well-known/openid-credential-issuer/acme
enabled: true
primaryEndpoint: true
createdAt: '2026-06-08T09:00:00Z'
updatedAt: '2026-06-08T09:00:00Z'