YAML Import Schema
ProAuth 3.x uses API-versioned YAML resources for CLI imports. The schema no longer uses YAML tags such as !CustomerDto or v1 DTO names. Each document declares its type with apiVersion and kind, and the CLI imports the file through the v2 Management API and v2 User Store API.
This page describes the v3 YAML standard used by:
proauthcli data importproauthcli label importproauthcli viewdefinition import- the matching
migrate-yamlcommands
WARNING
Legacy YAML files that use !TypeDto tags are not accepted by the ProAuth 3.x import commands. Convert them first with the corresponding migrate-yaml command.
API Versions
YAML apiVersion values describe the API family used by the CLI, not the ProAuth product version.
| Import area | apiVersion | Supported kind values |
|---|---|---|
| Management data | management.proauth.net/v2 | Management configuration entities |
| User Store data | userstore.proauth.net/v2 | User Store users and groups |
| Data import list wrapper | import.proauth.net/v1 | List |
| Labels and view definitions | management.proauth.io/v2 | LabelBundle, ViewDefinition, List |
Data Import Resources
Each data import document has the following shape:
apiVersion: management.proauth.net/v2
kind: Customer
metadata:
id: "09f43e7d-571a-4a24-b3d1-edf492640a0c"
spec:
name: 4tectureThe top-level fields are:
| Field | Required | Description |
|---|---|---|
apiVersion | Yes | Selects the Management API v2 or User Store API v2 resource family. |
kind | Yes | Selects the resource type. |
metadata | Yes | Contains import metadata. metadata.id is the entity ID. User Store resources also require metadata.userStoreId. |
spec | Yes | Contains the v2 create/update command fields and owned child configuration. |
relationships | No | Contains explicit relationship reconciliation rules. |
Top-level unknown fields are rejected. Unknown apiVersion or kind values are rejected.
Supported Data Kinds
Management resources use apiVersion: management.proauth.net/v2:
| Kind | Description |
|---|---|
Customer | Customer organization |
Subscription | Customer subscription |
Tenant | Tenant |
ClientApp | OAuth/OIDC client application |
ClientAppAuthenticationConfiguration | Client authentication method, certificate-bound token, DPoP settings, and tls_client_auth certificate metadata for a client application |
ClaimRule | Claim filter or transformation rule |
CertStore | Certificate store entry |
IPAddressRange | Tenant IP range |
IdpInstance | Identity provider instance |
MfaInstance | MFA instance |
ClientAppRole | Role assigned to a client application |
ProAuthUserRole | Role assigned to a ProAuth user |
ProAuthGroupRole | Role assigned to a ProAuth group |
ProAuthGroup | ProAuth group |
CustomView | Custom authentication view |
CustomAsset | Custom asset |
User Store resources use apiVersion: userstore.proauth.net/v2:
| Kind | Description |
|---|---|
User | User Store user |
Group | User Store group |
Multiple Documents And Lists
You can split imports across multiple files, use multiple YAML documents in one file, or wrap resources in a list.
Multiple documents:
apiVersion: management.proauth.net/v2
kind: Customer
metadata:
id: "{{guid:customer}}"
spec:
name: Example
---
apiVersion: management.proauth.net/v2
kind: Subscription
metadata:
id: "{{guid:subscription}}"
spec:
customerId: "{{guid:customer}}"
name: Example
status: activeList wrapper:
apiVersion: import.proauth.net/v1
kind: List
items:
- apiVersion: management.proauth.net/v2
kind: Customer
metadata:
id: "{{guid:customer}}"
spec:
name: Example
- apiVersion: management.proauth.net/v2
kind: Subscription
metadata:
id: "{{guid:subscription}}"
spec:
customerId: "{{guid:customer}}"
name: Example
status: activePlaceholder System
The v3 YAML format keeps the existing double-curly placeholder system.
| Placeholder | Description |
|---|---|
{{guid}} | Generates a new GUID. |
{{guid:name}} | Generates a GUID on first use and reuses the same value for the same name. |
{{secret:length}} | Generates a cryptographically secure random string. |
{{env:VARIABLE_NAME}} | Reads an environment variable. |
{{idptype:key}} | Looks up an IdP type by key. |
{{mfatype:key}} | Looks up an MFA type by key. |
{{proauthuserfromuserstore:idpInstanceId.userId}} | Resolves a ProAuth user from a User Store user. |
{{proauthgroupfromuserstore:idpInstanceId.groupId}} | Resolves a ProAuth group from a User Store group. |
Placeholders can be nested when a later lookup depends on a generated value:
proAuthUserId: "{{proauthuserfromuserstore:{{guid:userstore}}.{{guid:user}}}}"By default, dynamic lookup placeholders are resolved in memory. Use the import and migration options only when you intentionally want generated values written back to migrated or parsed output.
spec And Owned Child Configuration
The spec section contains the fields of the v2 create/update command for the resource. It can also contain owned child collections that belong to the resource.
Owned children are not relationship declarations. They are configuration objects whose lifecycle is owned by the parent.
CertStore resources support the legacy certificate and password fields as well as the v2 certificateInput object. Use certificateInput for PEM based automation:
apiVersion: management.proauth.net/v2
kind: CertStore
metadata:
id: "{{guid:certstore}}"
spec:
name: Tenant signing certificate
certType: OidcTokenSigning
applyToTenantId: "{{guid:tenant}}"
certificateInput:
pemCertificateFilePath: certs/tls.crt
pemPrivateKeyFilePath: certs/tls.key
password: "{{env:CERT_PASSWORD}}"Certificate file paths in CLI YAML imports are resolved relative to the YAML file and sent inline to the Management API. Passwords may be omitted when the private key or PFX is not password-protected.
ClientAppAuthenticationConfiguration uses the client application ID as its resource ID. The importer copies metadata.id to spec.clientAppId, so clientAppId can be omitted from the YAML:
apiVersion: management.proauth.net/v2
kind: ClientAppAuthenticationConfiguration
metadata:
id: "10000000-0000-4000-8000-000000000005"
spec:
tokenEndpointAuthMethod: tls_client_auth
requireCertificateBoundAccessTokens: true
tlsClientAuthSubjectDn: CN=identity-protocols-mtls-clientThe same resource also supports DPoP settings:
apiVersion: management.proauth.net/v2
kind: ClientAppAuthenticationConfiguration
metadata:
id: "10000000-0000-4000-8000-000000000006"
spec:
tokenEndpointAuthMethod: client_secret_post
dpopBoundAccessTokens: true
requireDpopNonce: trueAsymmetric client public keys are configured as ClientApp owned children named clientAppKeySets. Use key sets for private_key_jwt, JAR request-object signatures, self_signed_tls_client_auth, and token encryption:
apiVersion: management.proauth.net/v2
kind: ClientApp
metadata:
id: "{{guid:clientapp}}"
spec:
subscriptionId: "{{guid:subscription}}"
name: "Portal"
enabled: true
isPublic: false
clientAppKeySets:
- id: "{{guid:clientapp-private-key-jwt}}"
name: "Portal private_key_jwt signing keys"
sourceType: InlinePublicJwks
usage: ClientAssertionSigning
status: Active
jwksJson: '{"keys":[{"kty":"RSA","kid":"portal-signing-2026-01","use":"sig","alg":"RS256","n":"...","e":"AQAB"}]}'
- id: "{{guid:clientapp-token-encryption}}"
name: "Portal token encryption keys"
sourceType: RemoteJwksUri
usage: TokenEncryption
status: Active
jwksUri: "https://portal.example.com/.well-known/jwks.json"The keySets alias is also accepted, but clientAppKeySets is recommended for configuration repositories. The importer creates missing key sets and updates existing key sets by id.
Examples:
apiVersion: management.proauth.net/v2
kind: ClientApp
metadata:
id: "{{guid:clientapp}}"
spec:
subscriptionId: "{{guid:subscription}}"
name: "Portal"
enabled: true
isPublic: false
scopeFilterEnabled: true
resourceFilterEnabled: true
secrets:
- id: "{{guid:clientapp-secret}}"
name: "Default Secret"
secret: "{{env:CLIENTAPP_SECRET}}"
resources:
- id: "{{guid:clientapp-resource}}"
key: "ProAuthManagementService"
name: "PROAUTH_MANAGEMENT_SERVICE"
scopes:
- id: "{{guid:clientapp-scope}}"
key: "openid"
name: "openid"
redirectUris:
- id: "{{guid:clientapp-redirect}}"
uri: "https://portal.example.com/signin-oidc"
redirectType: RedirectUri
metadata:
- key: app
value: portalSupported owned child collections include:
| Owner kind | Owned child collections |
|---|---|
Tenant | options, ipAddressRanges |
ClientApp | secrets, clientAppSecrets, resources, clientAppResources, scopes, clientAppScopes, redirectUris, clientAppRedirectUris, federatedIdentities, clientAppFederatedIdentities, keySets, clientAppKeySets, metadata |
IdpInstance | options, metadata |
MfaInstance | options, metadata |
ProAuthGroup | metadata |
User | profiles, userProfiles |
Group | metadata |
Owned child imports run after the parent entity has been created or updated. Relationship imports run after all top-level entities and owned children have been processed.
Relationship Management
Relationships are declared in the relationships section. This replaces the legacy v1 style where navigation properties were sometimes embedded under either side of a relationship.
The goals are:
- relationships are explicit;
- the operation is deterministic;
- clearing a relationship is intentional;
- import files can be split across files without relying on nesting order.
Relationship Declaration Shape
Use this shape for new files:
relationships:
idpInstances:
mode: set
refs:
- "{{guid:userstore-idp}}"
- "88f30d7c-113d-4acf-bf8d-067bf6c67534"The shorthand form is also accepted and defaults to mode: set:
relationships:
idpInstances:
- "{{guid:userstore-idp}}"
- "88f30d7c-113d-4acf-bf8d-067bf6c67534"Use the explicit form for long-lived configuration files. It is clearer during review and makes destructive changes visible.
Relationship Modes
| Mode | Behavior |
|---|---|
set | Replaces the complete relationship set with refs. This is the default. |
add | Adds the referenced items and leaves existing items untouched. |
remove | Removes the referenced items and leaves all other existing items untouched. |
Omitting a relationship means the CLI does not manage that relationship. Existing database relationships stay unchanged.
Declaring an empty set clears the relationship:
relationships:
clientApps:
mode: set
refs: []An empty relationship declaration is equivalent to mode: set with no refs:
relationships:
clientApps: []Relationship References
For most relationships, a ref can be a string ID:
relationships:
tenants:
mode: set
refs:
- "14bb3908-d77b-4a5f-90ec-d4e7358e3194"Mappings are also accepted. This is useful when the same relationship list contains IDs that are easier to review with their target kind:
relationships:
tenants:
mode: set
refs:
- kind: Tenant
id: "14bb3908-d77b-4a5f-90ec-d4e7358e3194"The importer validates that relationship refs are not empty. Use refs: [] when you want to clear a relationship.
Supported Relationship Owners
Relationships can only be declared on registered owner kinds. If a relationship name is not valid for the selected owner kind, the import fails.
Management relationships:
| Owner kind | Relationship names |
|---|---|
Tenant | idpInstances, mfaInstances, clientApps |
ClientApp | tenants, idpInstances, mfaInstances, claimRules, allowedTokenExchangeClientApps, authorizedUsers, authorizedGroups |
ClaimRule | clientApps |
CertStore | idpInstances |
IdpInstance | tenants, certStores, clientApps, mfaInstances |
MfaInstance | tenants, idpInstances, clientApps, idpTypes, proAuthUsers |
ProAuthGroup | memberUsers, parentGroups, memberGroups |
User Store relationships:
| Owner kind | Relationship names |
|---|---|
User | groups |
Group | memberUsers, parentGroups, memberGroups |
Deterministic Ownership Guidance
Some relationships can be expressed from either side because the Management API exposes dedicated endpoints on both resources. To keep imports deterministic, pick one owner for each relationship in your configuration set and keep that ownership consistent.
Recommended ownership:
| Relationship | Recommended YAML owner |
|---|---|
| Tenant to IdP instances | Tenant.relationships.idpInstances |
| Tenant to MFA instances | Tenant.relationships.mfaInstances |
| Tenant to client apps | Tenant.relationships.clientApps |
| Client app to allowed token exchange apps | ClientApp.relationships.allowedTokenExchangeClientApps |
| Client app authorization users/groups | ClientApp.relationships.authorizedUsers / authorizedGroups |
| Claim rule to client apps | ClaimRule.relationships.clientApps |
| Cert store to IdP instances | CertStore.relationships.idpInstances |
| IdP instance to cert stores | IdpInstance.relationships.certStores |
| MFA instance to IdP types and ProAuth users | MfaInstance.relationships.idpTypes / proAuthUsers |
| ProAuth group membership | ProAuthGroup.relationships.memberUsers, parentGroups, memberGroups |
| User Store user group membership | User.relationships.groups or Group.relationships.memberUsers, but not both in the same import set |
| User Store group nesting | Group.relationships.parentGroups or Group.relationships.memberGroups, but not both for the same pair |
Avoid declaring the same relationship pair from both sides in the same import set. If both sides are declared with mode: set, the later relationship reconciliation can overwrite the earlier one and make the final result harder to reason about. The migration command reports relationship conflicts it can detect; review those warnings before committing migrated files.
Example: Tenant With IdP Relationship
apiVersion: management.proauth.net/v2
kind: Tenant
metadata:
id: "{{guid:tenant}}"
spec:
subscriptionId: "{{guid:subscription}}"
name: "Example Tenant"
accessGrantConsent: Inactive
logoutConsent: Inactive
relationships:
idpInstances:
mode: set
refs:
- "{{guid:userstore-idp}}"Example: User Store User And Group
User Store resources require both metadata.id and metadata.userStoreId.
apiVersion: userstore.proauth.net/v2
kind: User
metadata:
id: "{{guid:user-akira}}"
userStoreId: "{{guid:userstore-idp}}"
spec:
loginName: akira
firstName: Akira
lastName: Example
emailAddress: akira@example.com
passwordNeverExpires: true
emailAddressConfirmed: true
isUserActive: true
profiles:
- key: department
value: engineering
---
apiVersion: userstore.proauth.net/v2
kind: Group
metadata:
id: "{{guid:group-admins}}"
userStoreId: "{{guid:userstore-idp}}"
spec:
name: Admins
relationships:
memberUsers:
mode: set
refs:
- "{{guid:user-akira}}"Labels
Labels use apiVersion: management.proauth.io/v2 and kind: LabelBundle.
See Label Import And Export for detailed command usage, export filters, fallback behavior, and CI/CD guidance.
apiVersion: management.proauth.io/v2
kind: LabelBundle
metadata:
name: common-labels
spec:
entries:
- contentPath: /authviews/userlogin-sign-in
labels:
- language: en
fallback: true
content: Sign in
- language: de
fallback: false
content: AnmeldenImport labels:
proauthcli label import "./labels/*.yml"Exported label files are written in the same resource format.
ProAuth 3.x label content paths must use scoped roots such as /authviews, /accountmgmt, /oidc, /system, or /adminapp. Legacy /label and /page roots are not runtime fallback roots in ProAuth 3.x. Use proauthcli label migrate-yaml to rewrite legacy label files before import.
View Definitions
View definitions use apiVersion: management.proauth.io/v2 and kind: ViewDefinition.
apiVersion: management.proauth.io/v2
kind: ViewDefinition
metadata:
id: "c2f755a0-6538-45c1-5cb3-08d89133b8b5"
spec:
id: "c2f755a0-6538-45c1-5cb3-08d89133b8b5"
route: tenants
viewDefinitionType: ReaFx.Frontend.BlazorControls.Common.Models.ViewDefinitions.GridViewDefinition
definition: '{"id":"c2f755a0-6538-45c1-5cb3-08d89133b8b5","route":"tenants"}'Import view definitions:
proauthcli viewdefinition import "./viewdefinitions/*.yml"The CLI preserves legacy scalar semantics during migration. Blank legacy fields remain null, while explicitly quoted strings such as "true" remain strings.
Migration Commands
Convert legacy data import files:
proauthcli data migrate-yaml "./config/*.yml" --outputPath "./config-v3" --overwriteConvert labels:
proauthcli label migrate-yaml "./labels/*.yml" --outputPath "./labels-v3" --overwriteConvert view definitions:
proauthcli viewdefinition migrate-yaml "./viewdefinitions/*.yml" --outputPath "./viewdefinitions-v3" --overwriteThe label migration rewrites legacy label paths to the ProAuth 3.x scoped roots and preserves culture suffixes. The view definition migration rewrites full /page/... label IDs to /adminapp/...; short label IDs are left unchanged.
The data migration command also supports:
--replaceDynamicPlaceholders
--conflictStrategy fail|preferCanonicalOwnerThe data import and data parse commands resolve processed YAML in memory by default and do not modify the input file. Use --outputPath to write processed YAML to a separate folder, or --writeProcessedInput to explicitly write processed YAML back to the source file when no output folder is set.
Use the default --conflictStrategy fail for customer migrations. It stops when the old files contain incompatible relationship declarations that need human review.
After migration:
- Review the generated files and migration warnings.
- Commit the migrated YAML files to your configuration repository.
- Update deployment scripts to import the migrated files.
- Run the imports against a non-production ProAuth 3.x environment.
- Verify relationship-sensitive flows such as tenant login, user-store login, client app sign-in, role assignments, and group memberships.