> ## Documentation Index
> Fetch the complete documentation index at: https://docs.forge.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Azure AI Foundry

> Connect Azure AI Foundry and Azure OpenAI inventory with a Microsoft Entra service principal.

Forge uses a Microsoft Entra application and its service principal to poll Azure
Resource Manager. This is the inventory connection. Runtime telemetry, inline
policy enforcement, Agent access, containment, and rightsizing mutation use
separate authorities.

## What you need

Create the connection in **Settings → Integrations → Azure AI Foundry**. Have these
customer-visible values ready:

| Forge field         | Azure value                                                                                  |
| ------------------- | -------------------------------------------------------------------------------------------- |
| Azure subscriptions | Each **Subscription ID** Forge should poll, separated by commas                              |
| Resource group      | Optional exact resource-group name                                                           |
| Tenant ID           | Microsoft Entra **Directory (tenant) ID**                                                    |
| Client ID           | App registration **Application (client) ID**                                                 |
| Client secret       | The client-secret **Value**, not its Secret ID                                               |
| Access scope        | Leave blank for the standard setup so Forge requests `https://management.azure.com/.default` |

The **Access scope** field is an OAuth token scope, not an Azure RBAC resource
scope. Do not enter `/subscriptions/...`, `/resourceGroups/...`, or a management
group resource ID in that field. Assign Azure RBAC separately.

Forge does not ask for a Foundry project ID, project endpoint, Azure OpenAI
endpoint, deployment name, or redirect URI. It discovers supported resources
inside the subscription IDs you enter. A management-group role assignment does
not replace the subscription list; enter every subscription Forge should poll.

## Create the Entra application

You can use **Guided setup** in Forge, which creates an app registration, its
service principal, and a client secret. The generated comprehensive setup
assigns these roles at the selected Azure RBAC scopes:

| Azure role           | Purpose                                                                                       |
| -------------------- | --------------------------------------------------------------------------------------------- |
| Reader               | Discover resources through Azure Resource Manager                                             |
| Foundry User         | Enable rich Foundry list/read APIs; this Microsoft role includes broader project data actions |
| Monitoring Reader    | Optional: inspect Azure Monitor configuration during telemetry validation                     |
| Log Analytics Reader | Optional: query configured Log Analytics evidence during telemetry validation                 |

The generator requires explicit subscription IDs; it does not grant every
subscription visible to the signed-in Azure CLI account. Review the generated
RBAC scopes before running it. The Terraform alternative also creates the
application password, so protect the Terraform state and retrieve the secret
through its sensitive output. The Bicep alternative only assigns Reader to an
existing service-principal object ID; it does not create the Entra application
or its client secret.

To create it in the Azure portal instead:

1. Open **Microsoft Entra ID → App registrations → New registration**.
2. Name the app, for example `forge-cloud-ai-security`.
3. Select **Accounts in this organizational directory only**.
4. Leave **Redirect URI** unset and register the application. Forge uses the
   non-interactive OAuth 2.0 client-credentials flow, not browser consent or a
   callback.
5. On **Overview**, copy the **Application (client) ID** and **Directory
   (tenant) ID**.
6. Open **Certificates & secrets → Client secrets → New client secret**. Choose
   an expiry that matches your credential-rotation policy, create it, and copy
   the secret **Value** immediately.
7. For each subscription or narrower resource group Forge should read, open
   **Access control (IAM) → Add role assignment** and assign **Reader** and
   **Foundry User** to the new service principal. Add **Monitoring
   Reader** and **Log Analytics Reader** only when you also use the optional
   Azure Monitor and Log Analytics validation artifacts.

This connection does not require delegated Microsoft Graph permissions,
application API permissions, an admin-consent redirect, or a redirect URI.
Reader alone produces management-plane resource shells but cannot populate
Foundry agents and their associated configuration. Foundry User is
the additional role for rich Foundry data-plane reads; the monitoring roles are
not prerequisites for the normal Test or inventory Sync path.

Forge only performs list/read calls with the inventory connection. Microsoft does not
currently provide a built-in read-only role that covers all of the rich Foundry
project APIs Forge inventories, so **Foundry User** grants more data-plane
actions than Forge invokes. If that role is outside your access policy, keep
Reader only and expect management-plane inventory without rich agent details.

If you assign Reader only at a resource group, enter that resource group's
subscription ID and exact name in Forge. Be aware that some subscription-level
discovery calls can then return authorization blockers. Subscription-level
Reader is the straightforward setup for complete current inventory.

## Choose the Azure scope

* Add one or more subscription IDs. Forge polls each subscription separately.
* The optional **Resource group** value narrows Azure AI and Azure OpenAI
  account and deployment enumeration.
* The resource-group value also limits which discovered Foundry projects Forge
  reads through the data plane.
* Projects are discovered from Azure Resource Manager as
  `Microsoft.CognitiveServices/accounts/projects`; there is no project picker
  or project-endpoint credential in this connection.

## Save, test, and sync

1. Paste the subscription IDs, tenant ID, client ID, and client-secret value.
2. Optionally add one resource group. Leave **Access scope** blank.
3. Select **Save**. The secret is stored encrypted and is write-only; Forge does
   not return it to the browser.
4. Select **Test**. Test obtains a service-principal token and runs the Azure
   management-plane validation without importing inventory.
5. Select **Sync** to run and import the provider reads plus the separate
   workload and rich Foundry data-plane reads. Active integrations are also
   polled automatically on the deployment's configured sync schedule.

Test does not yet run the separate workload or rich Foundry collectors, so Sync
can report a data-plane or workload permission blocker that Test did not
encounter.

Changing the tenant ID or client ID changes the credential destination. Paste
the matching client secret in the same save operation. Leaving the secret blank
retains the stored secret only when those identity fields are unchanged.

## Current inventory

Sync imports Azure AI/OpenAI accounts and deployments, Foundry projects,
related Azure resources, and supported customer-hosted workloads. For each
discovered Foundry project, Forge also attempts rich reads for agents and
versions, hosted sessions, routines, workflows, tools, skills, files, vector
stores, connections, capability hosts, applications, and deployments.

Preview and region-specific Foundry surfaces can fail independently. Forge
retains inventory from the surfaces that succeed and reports the failed surface
as a bounded blocker instead of discarding the whole sync.

This connection does not enumerate general Foundry threads or reconstruct Azure
diagnostic logs as Forge sessions. It also does not currently inventory Azure
Monitor diagnostic settings, Log Analytics, or Application Insights as session
content. Workload inventory can discover ACR images, managed identities, and
relevant role assignments when their generated permissions and collectors are
enabled.

## Operator access and artifact scanning

Native NHI containment, identity rightsizing, and Agent access use a dedicated
federated application and bounded custom role. Guided setup keeps this operator
separate from the inventory service principal and reads back its federation,
role definition, assignments, and approved scopes before enabling actions.

ACR image scanning requires registry list and pull access from the current
generated setup. Filesystem snapshot scanning is opt-in and requires an exact
source subscription and resource group plus a dedicated
`forge-cloud-artifact-scanners` resource group. See
[Cloud artifact scanning](/observe/cloud-artifact-scanning).

## Expected states

| State                      | Meaning                                                                                    |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| Not connected / Not tested | No saved connection, or the saved connection has not been tested yet                       |
| Connected / Healthy        | The latest Test or Sync completed with no Azure blockers                                   |
| Needs attention / Degraded | Authentication or at least one Azure resource call failed; some inventory may still import |
| Disabled                   | Forge deleted the stored credential and paused polling                                     |

**Test** and **Sync** record the latest attempt time and show sanitized blockers
in the connection details. A degraded sync can still contain inventory from
subscriptions and resource families that succeeded.

## Recovery

* For `invalid_client`, an expired secret, or an AADSTS credential error, create
  a new client secret, paste its **Value** into **Client secret**, save, and run
  **Test** again.
* For tenant or application errors, verify the Directory (tenant) ID and
  Application (client) ID. If either changes, save it together with its matching
  secret.
* For `403` or `AuthorizationFailed`, verify **Reader** is assigned to the
  service principal at every entered subscription or an inherited parent scope.
  If **Test** succeeds but **Sync** reports a Foundry data-plane 403, also verify
  **Foundry User** on the affected Foundry account or project scope.
  Allow time for a new role assignment to propagate, then retest.
* If an expected project or deployment is missing, confirm its subscription is
  listed, the optional resource-group name is exact, and the service principal
  can read the resource's ARM scope.
* If Test is healthy but inventory is stale, run **Sync** and check the latest
  blockers and sync timestamp.

Disabling the integration removes Forge's stored credential and stops polling.
It does not delete the Entra application or Azure role assignments. Remove
those in Azure separately during offboarding. Remove APIM policies and
application callbacks separately if you configured runtime enforcement.

## Runtime enforcement

Inventory access does not place Forge in the Azure model request path. To make
policy decisions inline, route Azure OpenAI traffic through a customer-managed
APIM policy that calls Forge, or call Forge from a customer-owned
function/tool handler before execution. Direct SDK traffic and generic hosted
agent execution are not blocked by this inventory connection.
