Docs menu

OpenX AI App

Goal: Give the AI's Azure sign-in an app of its own, from inside OpenX, with nothing to do in a portal and nothing to run by hand.

The OpenX AI app is a multi-tenant Microsoft Entra app, created in a workspace's company directory. It is a registered app like any other in App Identity, under that workspace's company directory. Setting it up is a product flow: an AI proposes it, a person accepts it, and Deploy builds it. Any workspace with a company directory sets it up the same way, and the same three moves work the next time someone needs an app like this, in a new directory or a new environment.

Which app the AI signs in with. OpenX's AI sign-in to a person's Azure, the one that lists their subscriptions, uses one app for every workspace: the OpenX AI app on Fathym's root workspace (the workspace with no parent), under Fathym's own Entra directory. An OpenX AI app set up on any other workspace is created in that workspace's directory and recorded there. It belongs to that workspace, and OpenX's AI sign-in does not use it.

This page is for the workspace owner, or anyone who holds Workspace.Access.Manage there. It describes the setup from the screens OpenX shows. If a step you need is not on a screen, the page says so plainly instead of sending you somewhere else.

Before you start

  • The workspace has a company directory in App Identity that is complete (Company Azure AD, with its tenant). A B2C directory cannot hold this app.
  • You are the workspace owner or hold Workspace.Access.Manage. Anyone else sees the proposal but no Accept or Reject.
  • For the certificate choice only: the workspace's own Key Vault, from its private landing zone, is ready.

The three moves

MoveWhoWhereWhat it does
ProposeAn AI (Azi, or an agent connected over MCP)A proposal on the workspaceAsks for the app. Writes nothing
AcceptYouEnvironment -> App Identity -> Platform appsRecords the request on the directory
DeployYouDeployCreates the app in the directory and records what it made

1. An AI proposes the app

The proposal is a kind of its own, AISignInApps. It can carry only these fields:

FieldWhat it is
ProviderLookupThe workspace's company directory, as named in App Identity
DisplayNameThe name people see in their own directory. Left out, it is OpenX AI
HostsAt least one OpenX origin the sign-in returns to, such as www.openindustrial.co or localhost:5410, with no path. OpenX adds /workspace/azure-ai/callback to each one itself
PurposeWhy it is proposed, for the person who accepts. Never stored
CredentialKindfederated (the default) or certificate. You can change it when you accept

A proposal never carries a secret, an id, a scope or a credential: OpenX sets the audience, the permissions and the credential itself. It sits alone in its own bundle, and a directory holds one OpenX AI app. How an AI sends a proposal is on the proposals tool page.

An AI can only propose it once App Identity is configured, so a workspace with no directory yet answers IDENTITY_NOT_CONFIGURED and an operator sets one up first.

Refusals when it is proposed

An AI gets one of these back at once and nothing is stored.

CodeWhat it means
SECRET_IN_PROPOSALA field looks like a secret. The app never carries one, so the whole field is refused and its value is never echoed
APPLIED_FIELDThe field is one OpenX writes itself: the ids, credential, audience, scopes or reply URLs
UNKNOWN_AI_SIGNIN_APP_FIELDThe field is not part of this proposal, so it would be stored and never read
AI_SIGNIN_APP_HOSTS_REQUIREDNo OpenX origin was named
AI_SIGNIN_APP_HOST_INVALIDA host has a path, or is not an origin. OpenX adds the path itself
AI_SIGNIN_APP_NAME_BLANKDisplayName is blank. Give it a name or leave it out
AI_SIGNIN_APP_CREDENTIAL_KIND_INVALIDCredentialKind is not federated or certificate
AI_SIGNIN_APP_LOOKUP_INVALIDThe app's lookup is not lowercase letters, numbers and single hyphens, like openx-ai
AI_SIGNIN_APP_DIRECTORY_NOT_FOUNDProviderLookup names no App Identity in this workspace
AI_SIGNIN_APP_DIRECTORY_UNSUPPORTEDThe directory is B2C or another OpenID Connect directory. The app is created in a company Entra directory
AI_SIGNIN_APP_EXISTSThis directory already holds the app, requested or created
AI_SIGNIN_APP_BUNDLE_NOT_ALONEAnother proposal is in the same bundle. Move it to its own bundle
UNKNOWN_ROOT_KEYThe proposal hung a key on the record that is not part of it

2. You accept it in Platform apps

Open Environment -> App Identity on the workspace. After Access Cards there is a fifth tab, Platform apps, on every workspace. It says "OpenX's own Entra apps in this workspace's company directories, managed here like your directories' apps. The OpenX AI app is the one the AI's Azure sign-in uses."

With nothing waiting it reads "No platform app is requested yet. An AI proposes the OpenX AI app, and it appears here to accept."

A waiting proposal shows as Proposed: and the app's name, with its purpose, its Directory, and Returns to, the origins it named. If you can manage, you also see:

ControlWhat it does
Use a certificate instead of OpenX's managed identity (no secret either way)Unticked is the default, a federated credential with no secret. Ticked makes the credential a certificate in your Key Vault. Neither stores a secret
AcceptRecords the request on the directory and answers "Accepted. The request is recorded on the directory." Creates nothing yet
RejectRejects the proposal

When you accept, OpenX re-reads the proposal from the workspace itself, so nothing on the page can alter what is recorded. For a federated app it also fills in the managed identity the credential will trust, from the workspace's own deployment, so you never type it.

The app then appears in the tab as OpenX AI app with "Requested, not yet created", and the credential you chose. Nothing exists in the directory yet.

TIP

The line after "Requested, not yet created" still says the step that creates the app is not built. That sentence is out of date: the next Deploy is that step.

Accepting it through the generic proposal accept does not work. That door answers AI_SIGNIN_APP_ACCEPT_IN_APP_IDENTITY and leaves the proposal in place: "The OpenX AI app is accepted in the App Identity modal's Platform apps section. Open it there to accept or reject it. Nothing was accepted here."

Refusals when you accept

CodeWhat it means
access-manage-required"Only a workspace owner or an access admin can manage connected apps." You are not the owner and do not hold Workspace.Access.Manage
ai-signin-app-credential-kind-invalidThe credential is federated or certificate. Nothing was saved
proposal-not-found, not-an-ai-signin-app-proposal, proposal-not-pendingThe proposal is gone, is a different kind, or was already accepted or rejected. Reload
ai-signin-app-directory-unknownThe proposal names no App Identity in this workspace
commit-failed"The request was not saved. Try again."
AI_SIGNIN_APP_REQUEST_NOT_ALLOWEDA save, other than this tab, that asks for the app or changes the request was made by someone who is not the owner or a manage holder. "Only the workspace owner or someone with the 'Workspace.Access.Manage' right can ask OpenX to set up the OpenX AI app, or change that request."

3. Deploy creates the app

On the next Deploy, or the next save in App Identity that runs the directory's setup, OpenX acts on the recorded request, using the directory's own management app, read from the workspace's own landing zone, as it does for job identities and sign-in apps. Deploying needs the Workspace.Deploy right. OpenX does this, and nothing else:

StepWhat happens
The appCreated in your company directory under the name you gave. Anyone's Microsoft work or school account may sign in to it (multi-tenant)
Its permissionsExactly two: Azure Service Management's user impersonation, and sign-in (openid)
Its reply URLsOne per origin you named, each ending /workspace/azure-ai/callback
Its service principalCreated if the directory has none
Its one credentialFederated (the default): a trust that lets Microsoft accept OpenX's own managed identity as the app, so there is no password and no file to keep. Certificate: the workspace's own Key Vault generates the certificate, its private key never leaves the vault, and only the public part is bound to the app
The recordThe client id, object id, credential kind, tenant and active are written to the directory's record. For a certificate, the record holds a $secret: reference to it. Never a secret

No client secret is ever written, and a person never edits a setting, runs a script or opens a portal for any of this. The client id is kept on that record, not in a server setting.

The Platform apps tab then reads "Created in the directory.", with the Client ID. The commit's message says which kind it made:

  • "The OpenX AI app was created in the directory with a federated credential trusting the workspace runtime’s managed identity, and no secret."
  • "The OpenX AI app was created in the directory with a Key Vault certificate whose private key never leaves the vault, and no secret."

Deploying again is safe

Every Deploy re-checks the app. If it already matches, nothing is written. If a reply URL, a permission or the credential has drifted, OpenX brings it back to the one setup above, and the message says it was "checked and brought back to its setup". The certificate is read, not made again.

An app that already holds the name is used only if the directory's management app created it and it holds no client secret. Otherwise OpenX refuses it by name and touches nothing.

OpenX's own AI sign-in reads the app from Fathym's platform workspace. Keep to one OpenX AI app there: if two are recorded, the sign-in reads it as not set up rather than guess which one.

Refusals when Deploy builds it

A refusal is a message, never a failed Deploy. It records nothing, and the next save or Deploy tries again.

CodeWhat it means
AI_SIGNIN_APP_DIRECTORY_UNSUPPORTED"... it is created only in a company (Entra) directory named by its tenant."
AI_SIGNIN_APP_CREDENTIAL_KIND_UNKNOWN"... its credential kind must be 'federated' or 'certificate'." The Platform apps tab cannot record any other
AI_SIGNIN_APP_HOSTS_REQUIRED"... its request names no OpenX origin, so it would have no reply URL."
AI_SIGNIN_APP_HOSTS_INVALIDA host in the request is not an OpenX origin. The message says which
AI_SIGNIN_APP_ARM_SCOPE_UNKNOWN"... Azure Service Management's user impersonation permission could not be read from its service principal in this directory." Nothing was written
AI_SIGNIN_APP_IDENTITY_UNKNOWNA federated request: "the managed identity its federated credential must trust is not named on the request, or is not a managed identity in this directory." OpenX records the identity at accept; when the deployment had none, the request records none, and OpenX will not guess. The identity is looked up in the app's own directory, so in a directory where OpenX's managed identity does not exist, such as a customer's own, this is the answer today: choose Use a certificate there
AI_SIGNIN_APP_VAULT_NOT_READYA certificate request, and the workspace's Key Vault could not be opened. The message names why
AI_SIGNIN_APP_CERTIFICATE_UNREADABLE"The OpenX AI app's certificate was not bound: Key Vault returned no public certificate."
AI_SIGNIN_APP_UNTRUSTEDAn app under the name exists but was not created by this directory's management app, or holds a client secret, so OpenX did not use it
AI_SIGNIN_APP_MISSINGThe app the record names is no longer in the directory under its name. OpenX created no other and changed no app, because a new app would carry a new client id
DIRECTORY_NOT_REACHEDThe directory's management app could not be reached, or the run stopped part-way. Nothing was recorded

NOTE

OpenX has no screen yet to change a request after you accept it. A request that Deploy keeps refusing (AI_SIGNIN_APP_IDENTITY_UNKNOWN, for one) stays recorded and Deploy keeps retrying it. Choosing Use a certificate when you accept avoids that refusal, because a certificate needs no managed identity.

Customers' directories and admin approval

The app is multi-tenant, so people from other directories sign in to it. Publisher verification of the app is not done yet, so until it is, the app ships with administrator approval required in a customer's directory. A person there who signs in before their directory has approved it is stopped with Microsoft's AADSTS90094, which says the grant requires admin permission.

That approval is given by the customer's own directory administrator, in the customer's directory. OpenX does not do it for them, and nothing on this page does. When publisher verification is done, the app links its verified publisher.

Repeat the setup

The setup is the same each time, and every step is a screen or a Deploy:

  1. An AI proposes the app for the directory and the origins you need.
  2. You accept it in Platform apps, with the federated default or the certificate choice.
  3. You Deploy.

That is how to set it up in a new directory, or in a new environment. Deploying again also repairs an app that has drifted, so no one has to check it by hand.

Two things are not built yet, and the page does not invent a way around them: there is no screen to change a request after you accept it (for example to add another origin), and an app that vanished from its directory is refused by name rather than created again, because a new app would carry a new client id.

The Cloud-connect app

NOTE

This part is coming. It is not built yet, and nothing on screen does it today.

The app behind the browser's Cloud connect still signs in with a client secret that each runtime reads from its own settings. It will move to the same record and the same Deploy, in two steps, each its own change:

  1. Adopt. The record names the existing Cloud-connect app. OpenX adds a federated or certificate credential to it, and every runtime reads the client id and the credential from the record. The old secret keeps working, so nothing breaks while this lands. OpenX adopts only an app its own management app owns.
  2. Remove the secret. Once every runtime signs in with the record's credential and a person accepts it in App Identity, OpenX removes the app's secret and the runtimes stop reading it.

Until both are built, the Cloud-connect app is unchanged.

Next steps

On this page