On this page
Build & explore / Become an app
Your AUID.
Your permission model.
Every AXUS ID account can own an app context. Publish declarations under your AUID so AXUS ID can validate and describe the access your app supports.
Publish the complete definition.
Open Account → Developer → Permission declarations or call the mutation below. Use your own AUID as ownerAuid; it becomes the declaration context. Publishing requires your system capability identity.<owner>.grants.delegate.
mutation PublishPermission($owner: ID!, $declaration: PermissionDeclarationInput!) {
publishPermissionDeclaration(ownerAuid: $owner, declaration: $declaration) {
id context name version template title description icon validatorUrl order
}
}{
"name": "section.posts.create",
"template": "section.{section}.posts.create",
"params": [
{
"name": "section",
"type": "STRING",
"allowWildcard": true,
"allowedValues": [
"news",
"community"
],
"label": "Section",
"hint": "Choose the section where posts may be created."
}
],
"title": "Create posts in {section}",
"description": "Create posts in the {section} section.",
"icon": "file-plus",
"order": 10
}Every {param} template segment must have a matching entry in params. Empty literals and literal * or ? are reserved. Parameter names must be unique. Publishing the same name updates the existing declaration in place and increments its version. Keep the full definition in your app’s source and submit it again when updating.
Publishing defines valid keys; it does not create permission grants. Arrange initial app-context grants through the engine’s provisioning process, then use delegation for holders to share access.
Types, constraints and display metadata.
| Type | Binding |
|---|---|
STRING | Text in one dot-separated segment |
INTEGER | Signed 32-bit integer text |
LONG | Signed 64-bit integer text; keep it as a string |
DOUBLE | Numeric text; exponent notation avoids a dot within a segment |
BOOLEAN | Exactly true or false |
AUID | An AUID, including comma-separated nested IDs |
ParamDefInput supports name, type (default STRING), allowWildcard (default false), allowedValues: [String!], regex, minLength/maxLength, minNumber/maxNumber, and label, description, icon, hint. Numeric constraints use GraphQL Float. Allowed values remain strings for every type.
The declaration supports title, description, icon, validatorUrl, combinationInvariantJs and order. Lower order numbers appear first in declaration lists and permission pickers; declarations without an order come last, with names breaking ties. Titles and descriptions can interpolate bindings using {param}. The app can also personalize permission and parameter text through the describe protocol. The current publishing input does not expose static per-value metadata maps. The website renders recognized icon names such as key, shield, layers and file-plus, with a default icon for others.
For a range declaration with INTEGER parameters named from and to, a combination invariant can be function(bindings) { return Number(bindings.from) <= Number(bindings.to); }. AXUS ID evaluates it; frontend previews never execute the source. Avoid converting LONG values to JavaScript Number in your own invariants.
Validate large or changing sets in your app.
Use validatorUrl when static allowed values cannot represent the set, such as millions of users. AXUS ID calls the endpoint when granting a permission. It does not call it during permission evaluation.
{
"name": "identity.videos.edit",
"template": "identity.{subject}.videos.edit",
"params": [
{
"name": "subject",
"type": "AUID",
"allowWildcard": false,
"label": "Video owner",
"description": "The account whose videos may be edited.",
"hint": "Search for an account in this app."
}
],
"validatorUrl": "https://app.example.com/axus/permission-validator",
"title": "Edit videos owned by {subject}",
"description": "Edit this account’s videos in our app.",
"icon": "layers"
}{
"action": "validate",
"declarationId": "DECLARATION_UUID",
"bindings": {
"subject": "100000000"
}
}{"allowed": true}
{"allowed": false, "reason": "This account cannot edit these videos"}There is a two-second timeout and one retry. A timeout, unavailable endpoint or rejected verdict fails closed: no grant is created. Allowed verdicts are cached for 60 seconds and denied verdicts for 10 seconds. Make validation side-effect-free so retries are safe.
Return friendly values for the picker.
{
"action": "search",
"declarationId": "DECLARATION_UUID",
"param": "subject",
"query": "alex",
"limit": 20
}{
"values": [
{
"value": "100000000",
"label": "Alex",
"icon": "users",
"description": "Community video owner"
}
]
}Filter by the query and respect the limit. Search failure yields degraded: true to the picker instead of a search error. People can enter a raw value with the hint “Validated by app”; the subsequent grant still requires successful validation. Search suggestions and display labels are not authorization decisions.
Personalize permission text for each binding.
When someone previews a concrete permission with describePermission, AXUS ID sends its bindings to the same validatorUrl. Return only the fields you want to personalize. For example, your app can resolve an AUID to @likespro for the permission title and the parameter label.
{
"action": "describe",
"declarationId": "DECLARATION_UUID",
"bindings": {
"subject": "100000000"
}
}{
"title": "Edit videos owned by @likespro",
"description": "Edit @likespro’s videos in our app.",
"params": {
"subject": {
"label": "Video owner @likespro",
"description": "The account whose videos may be edited."
}
}
}title, description, and each parameter’s label and description are optional. Missing fields use the declaration text, with {param} replaced by the binding. If the endpoint fails or times out, the preview uses that declaration text. This affects display only; grant validation still uses the separate validate action.
Notify AXUS ID when validation data changes.
After changing data that affects verdicts, call notifyValidationChanged(declarationId) to drop cached allow and deny verdicts. This requires the declaration owner’s grants.delegate capability. The developer console also provides a manual Clear validation cache action.
mutation InvalidateValidation($declaration: ID!) {
notifyValidationChanged(declarationId: $declaration)
}Invalidation changes future grant validation. It is not grant revocation. Existing grants are evaluated without calling your endpoint; explicitly revoke access when your application needs to remove an existing grant.
Discover, describe and delegate.
Use the permission picker workflow and the GraphQL schema explorer for exact signatures and return types. Your app context must be forwarded with every identity permission check and delegation. OAuth scopes for your app use app:<your AUID>:<permission key>; unprefixed scopes use the AXUS ID system context.
Choose permission behavior when starting OAuth authorization: scope for access the app requires, optional_scope for features the user may decline, and conditional_scope for access required only when the account already holds it. Missing mandatory access stops sign-in with access_denied. Enable features from the approved scopes returned by the token endpoint. See the request and consent walkthrough.