# The enterprise stack, without the fog

Express course on the systems you meet inside a US mid-market company when you build AI agents there, current to October 2026. 42 concepts — Azure resource hierarchy, Managed Identity, Key Vault, Private Endpoint, Microsoft Foundry, IdP and SSO, OIDC and SAML, Entra ID app registrations and service principals, delegated vs application permissions, Conditional Access, Entra Agent ID, Okta, SCIM, Cross App Access, Snowflake virtual warehouses and service users, Cortex, Databricks Delta Lake and Unity Catalog, Agent Bricks, Microsoft Fabric OneLake and capacities, data agents, least privilege, security review and more — each with its English name, a diagram, and a card: what it is → example → catch → related. A one-page cheat sheet at the end.

- **Author:** Fedor Chishchin
- **Level:** intermediate
- **Reading time:** ~55 minute read
- **Published:** 2026-10-16
- **Source:** https://fedorthinks.com/learn/enterprise-stack-express

---

## 1. The map

Six product names, three jobs. Before any detail, learn which layer each system belongs to and where your AI project sits between them.

### The map: 42 concepts in eight chapters

> A metro map: first you see the whole set of lines, then you ride station by station.

The course follows the three layers. First the **cloud** — Microsoft Azure, where your code and the company's models run. Then **identity** — Microsoft Entra ID and Okta, which decide who may sign in and what they may touch. Then **data** — Snowflake, Databricks and Microsoft Fabric, where the company keeps its sales, finance and CRM numbers. The last chapter puts it all together: how an AI agent gets the smallest possible access, passes the client's security review, and doesn't wait three weeks for a role.

_Diagram: Three layers, six systems — chapters 2–7 follow them. Chapter 8 is how your agent plugs into all of them._

### How to read this course

> A passport: the same fields for everyone, so they're easy to compare.

Every concept gets its **English name** (the word you'll hear in meetings and read in docs), a picture from everyday life, a **diagram**, and a **card**: _what it is_, _example_, _catch_, and _related_ concepts. If you know Google Cloud, you'll see the mapping again and again: most enterprise systems are familiar ideas with different names. Product names change often here — Azure AD became Entra ID, Azure AI Foundry became Microsoft Foundry, Vector Search became AI Search — so the course gives the old name too. You will hear both at the client.

### Enterprise Stack — three layers, one project in the middle

> An office building: the landlord owns the floors (cloud), the security desk in the lobby checks badges (identity), and the archive in the basement holds every record (data). Your new tenant — the AI app — needs all three.

Every big company has the same three layers. The **cloud** is where code runs — at a Microsoft-heavy company, usually Azure. **Identity** is the company's directory of people and the front desk that signs them in — Entra ID or Okta. **Data** is where the company's records live — Snowflake, Databricks or Fabric, usually one of the three. Your AI app sits in the middle: employees sign in through the company's identity provider, the app runs in the company's cloud, and it reads data with the smallest rights it needs. In short: cloud is _where code runs_, identity is _who gets in_, data is _what they read_.

_Diagram: Employees sign in through Entra or Okta; your app gets a token, runs in the client's cloud, and reads from one data platform._

#### Enterprise Stack (cloud · identity · data)

- **What it is:** The three layers every large company runs: a cloud, an identity provider, and a data platform.
- **Example:** A logistics firm: Azure for code, Entra ID for sign-in, Snowflake for sales data — the AI agent touches all three.
- **Catch:** Each layer has its own admin, its own tickets and its own security rules. Access is usually the slowest part of the project.
- **Related:** Chapters follow the layers: **Azure**, **Entra ID / Okta**, **Snowflake / Databricks / Fabric**; it all meets in **Least Privilege**.

> **The framing question:** "For every system I touch: is this the cloud (where my code runs), the identity layer (who is allowed in), or the data layer (what I read) — and who is the admin I need on day one?"

> Six product names are really three jobs: the cloud runs the code, identity decides who gets in, and the data platform holds the company's records. Your agent lives between them.

## 2. Cloud: Microsoft Azure

Azure is Microsoft's cloud. If you know AWS or Google Cloud, you already know the ideas — what changes is the names, the strict folder structure, and how much of the security story runs on identities instead of keys.

### Microsoft Azure — the cloud companies pick 'because everything is Microsoft'

> Moving to a new city where the shops are the same but have different names: the supermarket, the pharmacy and the bakery are all there — you just need a new map.

**Microsoft Azure** is Microsoft's cloud, like AWS (Amazon) or Google Cloud: virtual servers, containers, databases, file storage, networks, queues. Plus access to models — OpenAI, Anthropic and others — through **Microsoft Foundry**. Why is it everywhere in mid-market companies? They already pay Microsoft for Office 365, Teams and Outlook, and their staff already sign in with a Microsoft work account. A second cloud would mean a new contract, a new sign-in system, new lawyers and a new security review. And for AI there's a bigger reason: many companies won't send data to the public `api.openai.com`, but models in Azure run inside _their_ cloud, under _their_ contract and access rules.

_Diagram: The same building blocks in three clouds. A Google Cloud project ≈ an Azure subscription + resource group; a service account ≈ a managed identity._

#### Microsoft Azure (Microsoft's cloud)

- **What it is:** Microsoft's public cloud: compute, storage, networks, databases and AI models.
- **Example:** A company on Office 365 runs its new AI assistant in Azure, billed on the same Microsoft contract and signed in with the same work accounts.
- **Catch:** Two kinds of rights: **Azure RBAC** (on resources) and Entra roles (on the directory) are different things. Contributor on a subscription does not let you create an app registration.
- **Related:** Organised by the **Resource Hierarchy**; sign-in comes from **Entra ID**; models from **Microsoft Foundry**.

### Resource Hierarchy — tenant → subscription → resource group

> Russian nesting dolls: the company holds folders of contracts, each contract holds project boxes, each box holds the actual things. Open the big doll and everything inside comes with it.

Azure is strict about structure, and you need it on day one because access and bills follow it. The **tenant** is the whole company in Microsoft's world — one directory of people and apps, living in Entra ID. A **management group** is a folder of subscriptions with shared rules (**Azure Policy**, such as "resources only in East US"). A **subscription** is a contract + a bill + an access boundary — usually separate ones for prod and dev. A **resource group** is a folder for things that live and die together: the app, its database, its vault. Delete the group and everything inside goes. The key rule: an **Azure RBAC** role (who can do what) given at a higher level applies to everything below it — so ask for a role on _one_ resource group, not the subscription.

_Diagram: Tenant → management group → subscription → resource group → resource. A role given above flows down to everything below._

#### Resource Hierarchy (tenant · subscription · resource group)

- **What it is:** Azure's nested folders: tenant → management group → subscription → resource group → resource.
- **Example:** Your access as a contractor: a guest account in their tenant and the Contributor role on `rg-ai-agent-dev` only.
- **Catch:** A new role can take up to about 5 minutes (sometimes longer) to start working. A 403 right after the grant is normal — wait.
- **Related:** The top level is the **Entra ID** tenant; roles are handed to a **Managed Identity**, a person or a group.

### Where Code Runs — App Service, Container Apps, AKS, Functions

> Ways to get to work: a bus that runs on a schedule (Functions), a taxi you just call (App Service), a car-sharing car you drive yourself but never maintain (Container Apps), your own car with all its servicing (AKS).

Azure has four common homes for your code. **App Service** — "just upload a web app"; like Heroku, an older style, runs Python, Node, .NET or a container. **Container Apps** — containers with no servers to think about and autoscaling down to zero; the closest thing to Google Cloud Run, and usually the best choice for an agent backend. **AKS (Azure Kubernetes Service)** — full Kubernetes, like GKE; pick it only if the client already has a Kubernetes platform. **Functions** — code that runs on an event (HTTP, timer, queue); good for background jobs like "a file arrived — process it".

_Diagram: From less to manage to more control. For an agent backend, Container Apps is usually the right default._

#### Container Apps (App Service · AKS · Functions)

- **What it is:** Azure's serverless containers — the usual home for an AI agent backend.
- **Example:** The agent's API runs as a Container App with its own managed identity and scales to zero at night.
- **Catch:** A forgotten AKS cluster or big VM costs hundreds or thousands of dollars a month. Put budget alerts on the resource group and delete dev resources.
- **Related:** Gets its rights through a **Managed Identity**; reaches services through **Private Endpoints**.

### Managed Identity — an account for your app, with no password at all

> A hotel key card that the front desk programs for you every morning: you never hold a master key, it only opens your rooms, and it stops working by itself.

A **managed identity** is an account for your application that Azure creates and looks after itself. There's no password and no key file: your code just asks Azure for a token. In practice you call `DefaultAzureCredential()` — on your laptop it uses your `az login`; inside a Container App it gets a short-lived token from Entra ID (it lives about an hour) through a local endpoint. Then you give that identity exactly the roles it needs, such as **Cognitive Services OpenAI User** on the Foundry resource. It's the Azure version of a Google Cloud service account, minus the JSON keys. There are two kinds: **system-assigned** lives and dies with one resource; **user-assigned** is a separate object you can attach to several resources.

_Diagram: The Container App asks Entra for a token, gets one that lives about an hour, and calls the model with it. No key exists to leak._

#### Managed Identity (system- or user-assigned)

- **What it is:** An Azure-managed account for an app: it gets tokens from Entra ID, never holds a password.
- **Example:** The agent calls the model with a token from `DefaultAzureCredential()` — no API key anywhere in code or config.
- **Catch:** Since October 2025 Microsoft is rolling out mandatory MFA for CLI, SDK and Terraform changes made as a user. Automate with a managed or workload identity, not your personal account.
- **Related:** A special kind of **Service Principal**; reads secrets from **Key Vault**; CI uses workload identity federation (OIDC) the same way.

### Key Vault — the safe for secrets

> A bank safe-deposit box: valuables don't sit in a desk drawer at the office, and only people on the list can open the box — with every visit written down.

Sometimes you do need a secret — say, an API key for the client's CRM, or a Snowflake private key. **Key Vault** is Azure's safe for secrets, keys and certificates, like Secret Manager in Google Cloud. The app reads a secret with its managed identity, which holds the **Key Vault Secrets User** role on that vault. Nothing sits in `config.yaml` or a `.env` file in git. This is the answer the security team wants to hear to "where are your secrets?".

_Diagram: Before: passwords in config files. After: the agent reads each secret from Key Vault with its own identity and a narrow role._

#### Key Vault (secrets · keys · certificates)

- **What it is:** Azure's managed store for secrets, keys and certificates.
- **Example:** The agent fetches the CRM key and the Snowflake private key from Key Vault at start-up.
- **Catch:** A vault closed with a private endpoint is unreachable from your laptop — plan a dev path.
- **Related:** Read through a **Managed Identity**; often hidden behind a **Private Endpoint**.

### Private Endpoint — services with no door to the internet

> An office building where the archive has no street entrance at all — you can only reach it through the inside corridor, after the lobby has let you in.

A **VNet (Virtual Network)** is the client's private network in Azure, like a VPC in Google Cloud. A **private endpoint** gives a service — Key Vault, Foundry, Postgres — a private IP address inside that VNet. After that, the service can be closed to the internet completely (`publicNetworkAccess: Disabled`). Corporate security loves this, and in mid-market companies it's often required. The price is on your side: your local code can't reach a closed service anymore. You'll need a VPN, a jump box, or a dev environment inside the VNet — and correctly set-up **private DNS**, the classic source of "why doesn't this name resolve?".

_Diagram: Inside the VNet, the agent reaches each service by a private IP. The internet — and your laptop — can't get in._

#### Private Endpoint (VNet · private link)

- **What it is:** A private IP for a cloud service inside the client's network, so it can be closed to the internet.
- **Example:** Foundry, Key Vault and Postgres each get an address like `10.0.1.4`; public access is disabled.
- **Catch:** It breaks access from your laptop and needs private DNS. Plan the dev path before the first deploy.
- **Related:** One of the first **Security Review** questions; the Google Cloud cousin is Private Service Connect.

### Microsoft Foundry — models inside the client's tenant

> A company canteen run by an outside caterer: the food is the same as in the caterer's restaurant, but it's cooked in your building, by your rules, on your contract.

**Microsoft Foundry** is Azure's AI platform. The name changed often: Azure AI Studio (2023) → Azure AI Foundry (2024) → **Microsoft Foundry** (from late 2025), and Azure OpenAI is now part of "Foundry Models". In one place you create a **model deployment** — your named copy of a model (say `gpt-4o-contracts`) with its own **quota**: **TPM** (tokens per minute) or **PTU** (capacity bought in advance). You build agents in **Foundry Agent Service** with tools and MCP, and you get evaluations, content filters and traces. Old Azure OpenAI endpoints and keys mostly keep working. The current token scope is `https://ai.azure.com/.default`; older examples use `https://cognitiveservices.azure.com/.default`.

_Diagram: Your code calls a deployment by its name; Foundry also hosts agents, evaluations and content safety. Three names in three years._

#### Microsoft Foundry (formerly Azure AI Foundry · Azure OpenAI)

- **What it is:** Azure's platform for models (including Azure OpenAI), agents and evaluations.
- **Example:** `model="gpt-4o-contracts"` — the field holds the deployment name, not the model name.
- **Catch:** The model you need may not exist in the client's region, or its TPM quota is too small. Check before you start, not on demo day. A 404 often means the wrong deployment name.
- **Related:** Called with a **Managed Identity** token, through a **Private Endpoint**; the Google Cloud cousin is Vertex AI, the AWS one is Bedrock.

> **The cloud question:** "Does my agent run with a managed identity, with roles on one resource group only, secrets in Key Vault, services behind private endpoints — and have I checked the model quota in their region?"

> Azure is a familiar cloud with stricter folders. Ask for one resource group, give your app a managed identity instead of keys, keep secrets in Key Vault, and check the model quota on day one.

## 3. Identity: SSO and Entra ID

Your app shouldn't check passwords. The company already has a front desk that knows every employee. This chapter covers the shared words — IdP, SSO, OIDC — and then Microsoft's front desk, Entra ID, where most confusion lives.

### Identity Provider and SSO — one front desk for every app

> The security desk in a business centre: the guard knows everyone by their badge. The offices upstairs don't check passports themselves — they trust the badge from the lobby.

An **identity provider (IdP)** is the system that confirms "this is Anna, and she's in Sales". Entra ID, Okta and Google are IdPs. **SSO (Single Sign-On)** is what people feel: they sign in once with their work account and then get into every app — Outlook, Salesforce, Jira, your agent — without new passwords. Before this, every app had its own login: fifteen passwords per person, half of them on sticky notes, new hires waiting a week for accounts, and people who left still able to open the CRM six months later. With an IdP, IT switches off one account and the access is gone everywhere — and there's one log of who signed in where.

_Diagram: The employee signs in once at the identity provider; every app — including yours — trusts that sign-in._

#### Identity Provider (IdP · SSO)

- **What it is:** The company's sign-in service; with it, one work account opens every app (SSO).
- **Example:** The internal agent has no login form — "Sign in" sends people to the client's Entra ID or Okta.
- **Catch:** You don't control it. Every change to how your app signs in goes through the client's IT.
- **Related:** Speaks **OIDC or SAML**; the two big ones are **Entra ID** and **Okta**.

### OIDC and SAML — how the app asks the front desk

> Two ways to prove you're a guest: a QR code on your phone that the door scans in a second (OIDC), or a stamped paper letter from the host that the guard reads line by line (SAML).

Two standards let your app "ask the front desk". **OAuth 2.0** is how you get an access token to call an API. **OIDC (OpenID Connect)** sits on top of OAuth for sign-in: it adds an **ID token** — a JWT that says who the person is. For a new web app, OIDC is the default. **SAML** is the older XML standard, still common in corporate SaaS; use it when the client insists. The usual OIDC flow is **authorization code + PKCE**: redirect to the IdP, the person signs in (with MFA), the IdP sends back a one-time code, your backend swaps it for tokens. Then you check the ID token: signature (keys from JWKS), `iss`, `aud`, expiry, `nonce`. For background work with no person, there's the **client credentials** flow; when your API calls another API for the user, there's **on-behalf-of (OBO)**.

_Diagram: Authorization code + PKCE: the browser goes to the IdP and back with a code, the backend swaps the code for tokens and checks them._

#### OIDC and SAML (OAuth 2.0 · auth code + PKCE)

- **What it is:** The standards your app uses to sign people in through the IdP. OIDC is modern JSON/JWT; SAML is older XML.
- **Example:** The same code-plus-PKCE flow you know from "Sign in with Google", pointed at `login.microsoftonline.com/<tenant-id>` or `acme.okta.com`.
- **Catch:** Never use the email as the user key — it changes. Use the stable ID: `oid` + `tid` in Entra, `sub` in Okta.
- **Related:** The IdP behind it is **Entra ID** or **Okta**; the app it talks to is an **App Registration**.

### Microsoft Entra ID — the company's directory in the cloud

> A company's staff directory crossed with a key cabinet: it lists every person and every group, and it hands out the keys.

**Microsoft Entra ID** — called **Azure AD** until 2023 — is Microsoft's cloud directory of a company's people and apps, plus its sign-in server. The **tenant** is one organisation's directory: it has an ID (a GUID) and domains like `contoso.com`. Inside are **users** (employees and **guests** — you, the contractor, usually join as a B2B guest with your own email), **groups** (security groups for rights; groups can be static or dynamic, like "everyone with department = Sales"), and **apps**. Many companies still run the old on-premises **Active Directory** and sync it into Entra with **Entra Connect**. The rule for your app: give rights to groups, not to people. IT adds someone to a group — they get access, and you never touch the code.

_Diagram: One tenant holds users (including guests), groups and apps. Old on-prem AD often syncs into it._

#### Microsoft Entra ID (formerly Azure AD)

- **What it is:** Microsoft's cloud directory and identity provider for employees, groups and apps.
- **Example:** The contract agent lets in only members of the `AI-Agent-Users` group of the `contoso.com` tenant.
- **Catch:** For an internal app, use the client's tenant ID — not `/common`, which lets in any organisation and personal accounts — and check `tid` in the token.
- **Related:** Apps live here as **App Registrations** and **Service Principals**; access is shaped by **App Roles** and **Conditional Access**.

### App Registration vs Service Principal — the passport and the visa

> A passport and a visa: the passport (registration) says who you are, once. A visa (service principal) is issued by each country you enter — and it's the visa that says what you may do there.

This is the pair everyone mixes up. An **app registration** is your app's passport: its **client ID** (public, not a secret), its **redirect URI** (where to send the person after sign-in — it must match exactly), its credentials, the permissions it asks for, the roles it declares. A **service principal** is the app's instance inside a specific tenant — in the portal it's called an **Enterprise application**. Rights are granted to the service principal, people are assigned to it, and Conditional Access applies to it. One registration can have service principals in many tenants — that's how SaaS products work. A **managed identity** is also a service principal, just one without a passport you have to manage. For credentials: a **client secret** expires (at most two years, often 6–12 months by policy); a certificate is better; a **federated credential** is best — nothing to expire.

_Diagram: The registration is the blueprint, made once. Each tenant that uses the app gets its own service principal, and that's what holds the rights._

#### App Registration vs Service Principal (Enterprise application)

- **What it is:** Registration = the app's definition (client ID, redirect URI, permissions, roles). Service principal = its copy in a tenant that gets rights.
- **Example:** "Contract Assistant": single-tenant registration, redirect URI `https://agent.contoso.com/auth/callback`, a federated credential instead of a secret.
- **Catch:** You probably can't create the registration or grant admin consent yourself — that's an Application Administrator. Send the exact list up front; it saves weeks.
- **Related:** Asks for **Delegated or Application Permissions**; declares **App Roles**; **Managed Identity** is a service principal too.

### Delegated vs Application Permissions — as the user, or as itself

> A personal assistant with your office key opens only your doors. A night guard with the master key opens every door in the building — useful for rounds, dangerous in the wrong hands.

There are two kinds of rights to call Microsoft APIs. **Delegated permissions** (scopes) — the app acts _on behalf of the signed-in user_ and sees only what that user sees: `User.Read`, `Files.Read`. In the token they appear in the `scp` claim. **Application permissions** — the app acts _by itself_, with no user, for background work: `Sites.Read.All` reads every SharePoint site. That's very powerful and always needs **admin consent**. **Consent** is the approval: "yes, this app may read my profile". A user can approve ordinary rights if the company allows it; strong rights only an admin can approve. Many companies switch user consent off entirely — hence the most common first-sign-in screen: **"Need admin approval"**.

_Diagram: Delegated: the agent sees only Anna's files. Application: it sees every site — and needs an admin to approve._

#### Delegated vs Application Permissions (scopes · consent · admin consent)

- **What it is:** Delegated = act as the signed-in user, within their rights. Application = act as the app itself, across everything granted.
- **Example:** A SharePoint Q&A agent uses delegated `Sites.Read.All`, so SharePoint applies each user's own rights automatically.
- **Catch:** Application permissions bypass people's rights. With application `Sites.Read.All`, an agent answering employees can easily show someone a document they shouldn't see.
- **Related:** The heart of **As the User vs As Itself**; the first question of the **Security Review**.

### App Roles — your own roles, assigned by their IT

> Coloured wristbands at a festival: the organiser decides what a blue band opens, the ticket desk hands bands out, and the gate only looks at the colour.

**App roles** are roles you declare in your app registration — say `Agent.User` and `Agent.Admin`. The client's IT assigns them to groups. When someone signs in, their roles arrive in the token's `roles` claim, and your backend checks them: no `Agent.User` → 403. Turn on **"Assignment required"** and people who aren't assigned can't even sign in. Why not just read the groups from the token? Because of **groups overage**: if a user is in too many groups (more than 200 for a JWT), the groups don't arrive in the token at all — you get a link to Graph instead. App roles avoid that, and they keep control with the client: IT moves people between groups, you never touch the code.

_Diagram: You declare roles, IT assigns them to groups, they arrive in the token, your backend checks them._

#### App Roles (roles claim · assignment required)

- **What it is:** Roles declared by your app, assigned by the client's IT to groups, delivered in the token.
- **Example:** `if "Agent.User" not in claims.get("roles", []): abort(403)` — Finance gets `Agent.Admin` through its group.
- **Catch:** Relying on the groups claim instead breaks for people in more than 200 groups — the groups simply aren't in the token.
- **Related:** Declared in the **App Registration**; the Okta equivalent is a filtered groups claim.

### Conditional Access — rules at the door

> A club bouncer with a list of rules: members walk in, guests show ID, nobody gets in wearing trainers — checked at the door every single time.

**Conditional Access** is a set of "if — then" rules that Entra checks at every sign-in: _if_ someone from the Finance group opens app X from an unmanaged device, _then_ require MFA — or block. Conditions can include the user or group, the app, the device, the location and the sign-in risk. **MFA** is the second factor: a push in Microsoft Authenticator, a FIDO2 key, a passkey. Conditional Access needs an **Entra ID P1** licence or higher; small tenants without P1 may have only **security defaults** (MFA for everyone). Risk-based access and PIM need P2, and Conditional Access for service principals needs a separate Workload Identities licence. "We don't have that feature" often means "we don't have that licence".

_Diagram: At each sign-in Entra checks who, which app, which device, where, how risky — then allows, asks for MFA, or blocks._

#### Conditional Access (MFA · security defaults)

- **What it is:** Sign-in rules in Entra ID: conditions (who, app, device, place, risk) → action (allow, MFA, block).
- **Example:** The contract agent automatically falls under the company's "MFA plus managed device" policy.
- **Catch:** "Managed devices only" can block your tests, your CI and your own laptop. Agree on exceptions early, and check the dev environment isn't locked out.
- **Related:** Applies to the **Service Principal**; Okta's version is authentication policies.

### Microsoft Graph — one API to all of Microsoft 365

> A building's central switchboard: one number connects you to any office — mail room, calendar desk, file archive — instead of a separate phone line for each.

**Microsoft Graph** is one big API to everything in Microsoft 365: users, groups, mail, calendars, Teams, files in OneDrive and SharePoint. The address is `https://graph.microsoft.com/v1.0/…`. For an AI agent it's the main door to the client's documents: "find contract 42 in SharePoint", "book a meeting". With a delegated token, Graph returns only what the signed-in user may see — so the agent's search tool inherits SharePoint's permissions for free. The old Azure AD Graph API is switched off; only Microsoft Graph is left. The official library for sign-in and tokens is **MSAL** (Python, JS, .NET and more).

_Diagram: The agent calls one endpoint, graph.microsoft.com, and reaches users, mail, calendars, Teams and files — within its scopes._

#### Microsoft Graph (graph.microsoft.com · MSAL)

- **What it is:** The single REST API to Microsoft 365 data.
- **Example:** The agent's search tool calls `POST /v1.0/search/query` with the user's access token and gets only documents that user can open.
- **Catch:** What Graph returns is bounded by the scopes in the token. Ask for too little and calls fail; ask for too much and security review stalls.
- **Related:** Called with **Delegated or Application Permissions**; the token comes from **OIDC** sign-in.

### Entra Agent ID — an identity made for AI agents

> A staff badge for a robot: it has its own photo, its own access list, shows up in the visitor log, and security can deactivate it at the desk like anyone else's.

In 2026 Entra got a separate kind of identity for AI agents: **Agent ID** (generally available since April 2026). An agent gets its own identity, created from a template — an **agent identity blueprint** — and IT manages it like an employee: permissions, Conditional Access, sign-in logs, switching it off. It answers a question security teams now ask often: "how do we know which agents exist and what they can do?". It's new, so it's worth knowing the word and asking the client whether they use it.

_Diagram: Agents are created from a blueprint, each with its own identity, and IT controls them like staff accounts._

#### Entra Agent ID (agent identity blueprint)

- **What it is:** A first-class Entra identity type for AI agents, created from a blueprint and governed like a user.
- **Example:** The contract agent and the sales agent each get their own Agent ID with separate rights and logs.
- **Catch:** New in 2026 — many mid-market tenants haven't adopted it yet. Ask, don't assume.
- **Related:** Okta's counterpart is **Cross App Access** with Agent SSO; both serve **Least Privilege**.

> **The identity question:** "Does my app sign people in through the client's tenant with OIDC, use the stable user ID, check app roles — and act with delegated permissions whenever it answers a person?"

> Entra ID is the company's directory and front desk. Register the app, let IT assign app roles to groups, prefer delegated permissions, and send IT one precise list so admin consent is fast.

## 4. Identity: Okta

Okta does the same job as Entra ID, but it's an independent company. It wins where the client runs a mix of tools and Microsoft isn't the centre. The standards are the same; the words and the admin console differ.

### Okta Workforce Identity — the neutral front desk

> A front desk run by an independent security firm rather than the landlord: it works with every tenant in the building, whatever brand of door lock each office uses.

**Okta Workforce Identity** is Okta's product for employees: it knows every person in the company and decides who may sign in where. People sign in once and get into Slack, Salesforce, Jira, AWS and your app. Companies pick it when they have a "zoo" — Google Workspace, AWS, Slack, Salesforce, Macs — and Microsoft isn't the main vendor; its catalogue, the **Okta Integration Network (OIN)**, has more than 8,000 ready integrations. Each company has an **org** with an address like `acme.okta.com` — the Okta version of a tenant. Usually there's a production org and a **preview org** (on `oktapreview.com`): ask for access to the preview one first. **Universal Directory** holds people (with fields like department and manager), groups and now AI agents; data usually flows in from the HR system — "HR is the source of truth". Don't confuse Okta with **Auth0**: same company, but Auth0 is for a company's _customers_ signing into its product; Okta Workforce is for _employees_.

_Diagram: People flow in from HR and AD; the Okta org holds the directory, policies, token servers and lifecycle; apps — and your agent — trust it._

#### Okta (Workforce Identity · org · Universal Directory)

- **What it is:** An independent cloud identity provider for employees: directory, SSO, MFA, provisioning.
- **Example:** The agent is an OIDC app integration in `acme.okta.com`, assigned to the `AI-Agent-Users` group.
- **Catch:** By default, groups aren't put in the token. You need a groups claim with a filter (say "starts with AI-Agent-") — "all groups" bloats the JWT and breaks headers and cookies.
- **Related:** Same standards as **Entra ID** (**OIDC and SAML**); provisioning by **SCIM**; tokens from **Authorization Servers**.

### SCIM — joiners, movers and leavers, automatically

> When a new hire's name goes on the HR list, a badge, a desk and a locker appear on day one; when they leave, the badge stops working that same evening — without anyone remembering to do it.

**SCIM** is a standard REST API for creating, updating and switching off users in an app. The IdP — Okta or Entra — is the SCIM client; your app is the SCIM server, with `/Users` and `/Groups` endpoints. **Lifecycle management** covers the three moments: **joiner** (someone is assigned the app → `POST /scim/v2/Users`), **mover** (they change team → group updates), **leaver** (they leave → `PATCH` with `active=false`: the account is switched off, not deleted). Without SCIM, users only appear in your database at their first sign-in (**just-in-time**), and nobody removes the people who left — "dead souls" with their chat history and settings.

_Diagram: HR changes something, the IdP calls your SCIM endpoint: create on join, update on move, deactivate on leave._

#### SCIM (provisioning · joiner–mover–leaver)

- **What it is:** A standard API through which the IdP creates, updates and deactivates users in your app.
- **Example:** Someone leaves on Friday; Okta sends `PATCH active=false` and their agent account is off that same day.
- **Catch:** Only matters if your app keeps its own user records. If it does and you skip SCIM, you'll have accounts that outlive their owners.
- **Related:** Driven by **Okta** or **Entra ID**; pairs with short-lived tokens for fast revocation.

### Authorization Servers — org or custom

> A building has one standard pass that opens the main doors, but a lab with special rules prints its own passes with its own stamps. Showing the standard pass at the lab door doesn't work.

The part of Okta that issues tokens is an **authorization server**, and there are two kinds. The **org authorization server** is built in, with issuer `https://acme.okta.com`; it's fine for ordinary sign-in and for calling Okta's own API, but you can't add your own scopes. A **custom authorization server** (issuer like `https://acme.okta.com/oauth2/default`) protects _your_ APIs: your scopes such as `agent.read` and `agent.tickets.write`, your claims, your policies, machine-to-machine. It needs the paid **API Access Management** subscription — the client may not have it. The classic mistake: validating an org-server token in your own API as if it were your access token. If you build an API, you need a custom server. Find out the issuer first.

_Diagram: The org server handles sign-in and Okta's own API; a custom server issues tokens with your scopes for your API._

#### Authorization Server (org vs custom · issuer)

- **What it is:** Okta's token issuer. Org = built in, for SSO; custom = your scopes and claims, for your APIs.
- **Example:** The backend checks tokens against issuer `…/oauth2/default`, audience `api://ai-agent`, keys from `/v1/keys`.
- **Catch:** Mix them up and the `aud` check fails, or you can't add a scope. For calls to Okta's API, use an OAuth service app — not a static SSWS token, which breaks when its admin leaves.
- **Related:** Issues the tokens of **OIDC**; agents can reach other apps through **Cross App Access**.

### Cross App Access and Agent SSO — agents that don't hoard tokens

> Instead of every assistant carrying a ring of copied keys to every office, the front desk issues a short visitor pass for each visit — and writes every visit in the book.

The new problem: an agent in app A wants data from app B on the user's behalf. The old way, each user clicks "connect your Jira" in each app, and the agent stores those tokens — and IT can't see any of these links. **Cross App Access (XAA)** is an open protocol, built on the IETF draft **ID-JAG** (Identity Assertion JWT Authorization Grant): the agent asks Okta, Okta checks policy and issues a short token for app B, and Okta sees and logs every such link. XAA has been accepted as an Enterprise-Managed Authorization extension for MCP; partners include Slack, Atlassian, Zoom, Asana, Datadog, Cloudflare and Claude. **Agent SSO** (generally available since August 24, 2026, included in standard Okta SSO at no extra cost) registers an XAA-capable agent as its own identity in Universal Directory, next to people, with short-lived tokens instead of static API keys. Beyond that, **Okta for AI Agents** is a separate paid subscription for discovery and governance. On the customer side, **Auth0 for AI Agents** (GA since November 2025) offers a Token Vault, async approval by a human, and fine-grained access for RAG.

_Diagram: Old way: users connect each app and the agent keeps the tokens. XAA: the agent asks Okta, gets a short token as the user, and Okta logs it._

#### Cross App Access (XAA · ID-JAG · Agent SSO)

- **What it is:** An Okta-brokered way for an agent in one app to get a short, logged token for another app, as the user.
- **Example:** A sales agent creates Jira tickets through XAA — nothing to store, and IT sees the link in Okta.
- **Catch:** Works only if both the agent's app and the resource app support it. Many mid-market clients won't have it on — keep plain OAuth with minimal scopes as plan B.
- **Related:** Microsoft's counterpart is **Entra Agent ID**; it's **As the User**, done centrally.

> **The Okta question:** "Do I know the issuer and which authorization server it is, is the groups claim filtered, do I need SCIM — and can my agent use Cross App Access instead of storing tokens?"

> Okta is the neutral front desk: the same OIDC you already know, plus SCIM for joiners and leavers, two kinds of token servers, and now Cross App Access so agents stop hoarding tokens.

## 5. Data: Snowflake

Where does the company keep its numbers? First the three shapes data storage can take. Then Snowflake — the SQL warehouse where storage and compute are split, and you pay by the second.

### Warehouse, Lake, Lakehouse — three ways to keep company data

> A library, a garage and a modern archive. The library has strict shelves and a catalogue but takes only finished books. The garage takes anything, but finding something is a nightmare. The archive keeps everything in cheap boxes — with a catalogue on top.

A **data warehouse** is a database built for analysis, not for running an app: big strict tables and heavy queries like "sales by region for three years", in SQL. Fast and reliable, but pricier, and only the clean part of the data goes in. A **data lake** is just folders of files in cloud storage — S3, ADLS, GCS: logs, CRM exports, CSV, JSON, images. Cheap and huge, but no order: no transactions, files break on concurrent writes, nobody knows which version is right. For years companies ran both and copied data back and forth — two copies, two sets of rights, reports that disagreed with models. A **lakehouse** (lake + warehouse) keeps data once in cheap storage, in a table format that adds transactions, schema and history, so SQL, Spark and ML all work on the same tables.

_Diagram: Warehouse: strict and clean. Lake: cheap and messy. Lakehouse: files once, with table rules on top. Snowflake started as the first; Databricks and Fabric are the third._

#### Warehouse · Lake · Lakehouse (data warehouse · data lake)

- **What it is:** Three storage shapes: strict SQL tables, raw files of any kind, or files with a table format on top.
- **Example:** Finance reports live in a warehouse; app logs land in a lake; a lakehouse serves both from one copy.
- **Catch:** Today Snowflake, Databricks and Fabric all do almost everything and compete hard — the labels describe where each one started.
- **Related:** **Snowflake** (warehouse roots), **Databricks** and **Microsoft Fabric** (lakehouse on **Delta Lake**).

### Snowflake — storage in one place, compute on demand

> A huge warehouse of goods with separate crews of movers you hire by the minute. Need it faster — call a bigger crew. Nobody working — nobody paid.

**Snowflake** is a cloud database for analytics. The company pours its data in — sales, CRM, inventory, finance — and every department queries it in plain SQL. Servers, disks, indexes, backups are Snowflake's job. The big idea is that **storage is separate from compute**: one copy of the data, and each team gets its own compute cluster that doesn't slow the others down. There are three layers: **cloud services** (the brain — sign-in and roles, metadata, query optimiser, result cache), **compute** (virtual warehouses, paid in credits), and **storage** (columnar data in micro-partitions, paid per TB a month). Snowflake runs on top of AWS, Azure or GCP — the client picks the cloud and region. Your **account** has an identifier like `myorg-myaccount`; the web console is **Snowsight**. Bonuses: **Time Travel** reads a table "as it was yesterday" (1 day by default, up to 90 on Enterprise), and **zero-copy clone** makes a dev database from prod in seconds.

_Diagram: Three layers: the brain on top, separate compute clusters per team in the middle, one shared copy of the data at the bottom._

#### Snowflake (cloud data warehouse)

- **What it is:** A SQL analytics platform where storage and compute are separate and compute is billed by use.
- **Example:** The agent's queries run on their own small cluster, so the BI team's dashboards don't slow down.
- **Catch:** Unquoted names become UPPERCASE: `"orders"` in quotes and `orders` are different tables. And use the new `org-account` identifier, not the old locator format.
- **Related:** Compute is a **Virtual Warehouse**; access is **Roles and RBAC**; AI is **Cortex**.

### Virtual Warehouse — a compute cluster, not a store

> A taxi with a meter: it comes when you call, the meter runs only while you ride, and it drives off when you're done. A bigger car costs more per minute.

The word confuses everyone: a **virtual warehouse** stores nothing. It's a compute cluster that runs your queries. It has a size — X-Small, Small, Medium, Large, up to 6X-Large — and each step up is twice the power and twice the price. Price is in **credits**, Snowflake's internal currency: X-Small burns 1 credit per hour, Small 2, Medium 4, Large 8, X-Large 16 (Gen1). The dollar price of a credit depends on edition, cloud, region and contract — there's no single number. Billing is per second, with a minimum of 60 seconds at every start. **Auto-suspend** puts the cluster to sleep when idle (set 60 seconds); **auto-resume** wakes it on the next query; **multi-cluster** (Enterprise) adds copies under load. A **resource monitor** caps credits: notify at 80%, suspend at 100%. Without an active warehouse, SQL won't run: "No active warehouse selected".

_Diagram: Each size doubles the credits per hour. Wake on query, bill per second, sleep after 60 seconds of quiet — and cap it with a resource monitor._

#### Virtual Warehouse (credits · auto-suspend · resource monitor)

- **What it is:** A Snowflake compute cluster with a size and a per-second credit price; it holds no data.
- **Example:** `AI_AGENT_WH`: X-Small, `AUTO_SUSPEND = 60`, a resource monitor of 50 credits, and a `QUERY_TAG` to track the agent's cost.
- **Catch:** No auto-suspend or too big a size = thousands of dollars a month. An agent that fires 20 queries per question keeps the warehouse awake all day.
- **Related:** The compute layer of **Snowflake**; used through a **Role**.

### Roles and RBAC — rights go to roles, roles go to users

> Keys on a hook board labelled by job, not by name: "cashier", "night manager". New staff get the hook for their job; nobody is handed loose keys.

In Snowflake, rights are never given to a user directly: they go to **roles**, and roles go to users. This is **RBAC (role-based access control)**. Built-in roles: **ACCOUNTADMIN** — god of the account (nobody will give it to you, and you don't need it); **SECURITYADMIN** and **USERADMIN** manage users and grants; **SYSADMIN** creates databases and warehouses; **PUBLIC** everyone has. Roles can nest. For the agent you create its own role, say `AI_AGENT_RO`, with `USAGE` on its warehouse, database and schema, and `SELECT` on the views it needs — plus `SNOWFLAKE.CORTEX_USER` if it calls Cortex. On top, **row access policies** decide which rows someone sees, and **masking policies** hide values like email or SSN. Objects are named `DATABASE.SCHEMA.OBJECT`, such as `SALES.MART.ORDERS_V`.

_Diagram: The service user gets one read-only role; the role holds the grants. Built-in roles sit above, from ACCOUNTADMIN down to PUBLIC._

#### Roles and RBAC (AI_AGENT_RO · row access · masking)

- **What it is:** Snowflake's access model: grants go to roles, roles go to users and to other roles.
- **Example:** `GRANT SELECT ON ALL VIEWS IN SCHEMA SALES.MART TO ROLE AI_AGENT_RO` — views only, never raw PII tables.
- **Catch:** "Object does not exist" or "no warehouse" is almost never a typo — it's a missing `USAGE` grant. Snowflake says "does not exist" when the role can't see it.
- **Related:** Given to a **Service User**; a textbook case of **Least Privilege**.

### Service User — a Snowflake account for a program, no password allowed

> A delivery robot gets into the building with a programmed chip, not by typing the door code — and the building simply doesn't let robots use codes anymore.

A **service user** (`TYPE = SERVICE`) is a Snowflake user for a program, not a person. Passwords are forbidden for it: it signs in with a **key pair** (JWT), OAuth, a programmatic access token (PAT), or workload identity federation. And this is now strict: between August and October 2026 Snowflake fully blocked password sign-in for service users, and `LEGACY_SERVICE` users are being moved to `SERVICE`. So the old internet examples with `password=` don't work — don't copy them. With **key-pair auth**, you generate an RSA key pair, give the admin the public key (`RSA_PUBLIC_KEY`), and keep the private key in Key Vault or Secret Manager. Your connector signs a JWT with it (`authenticator="SNOWFLAKE_JWT"`). A second slot, `RSA_PUBLIC_KEY_2`, lets you rotate keys without downtime; a **network policy** limits which IPs may connect.

_Diagram: No password. The private key in the vault signs a JWT; Snowflake checks it against the public key, the network policy and the role._

#### Service User (TYPE = SERVICE · key-pair auth)

- **What it is:** A Snowflake user for software, which must sign in with a key, OAuth, PAT or workload identity.
- **Example:** `SVC_AI_AGENT` with `DEFAULT_ROLE = AI_AGENT_RO`, `DEFAULT_WAREHOUSE = AI_AGENT_WH`, and only an RSA public key.
- **Catch:** If every user of the agent goes through one service user, everyone sees the same data. Decide early: row policies, or sign-in as the user via OAuth from Okta or Entra.
- **Related:** Holds a **Role**; keys live in **Key Vault**; the design choice is **As the User vs As Itself**.

### Cortex — AI next to the data

> Instead of carrying the archive's boxes to an outside expert, you invite the expert into the archive — the papers never leave the building.

**Cortex AI** is Snowflake's AI layer, with models from Anthropic, OpenAI, Meta, Mistral and others running inside Snowflake's security boundary. **Cortex AI Functions** (formerly "AISQL") put an LLM straight into SQL: `AI_COMPLETE`, `AI_CLASSIFY`, `AI_EXTRACT`, `AI_SENTIMENT` — classify 100,000 reviews in one query. **Cortex Analyst** turns an English question into SQL using a **semantic view** that defines business terms ("revenue = SUM(amount) where status = 'paid'"). **Cortex Search** is ready-made RAG search over text: vectors + keywords + reranking. **Cortex Agents** (GA since November 2025) plan steps and call Analyst, Search, your procedures and MCP connectors; on August 28, 2026 Snowflake recommended moving from the separate Analyst API to Cortex Agents. **Snowflake Intelligence** is a ready chat UI on top. A **Snowflake-managed MCP server** (`CREATE MCP SERVER`, up to 50 tools) exposes all this to outside agents like Claude or Cursor, with Snowflake OAuth or external OAuth from Okta or Entra.

_Diagram: Functions, Analyst, Search, Agents, Intelligence — all inside Snowflake. The managed MCP server opens them to outside agents._

#### Cortex (AI Functions · Analyst · Search · Agents)

- **What it is:** Snowflake's built-in AI: LLM functions in SQL, text-to-SQL, RAG search and agents, next to the data.
- **Example:** Path B for a "why did margin drop in Texas?" agent: a semantic view + a Cortex Agent, called from your app — the data never leaves Snowflake.
- **Catch:** Cortex calls cost credits per token — a separate line on the bill; try 1,000 rows before a million. Not every model is in every region. And text-to-SQL without a semantic layer lies: nobody knows what `AMT_NET_2` means.
- **Related:** Agents reach it through **MCP**; the Databricks cousin is **Agent Bricks**, the Fabric one is the **Data Agent**.

> **The Snowflake question:** "Does my agent have its own service user with a key, a read-only role on views, a small warehouse that sleeps after a minute, a resource monitor — and a semantic layer before any text-to-SQL?"

> Snowflake splits storage from compute and bills compute by the second. Give the agent its own key-signed service user, a read-only role, an X-Small warehouse and a credit cap — and send the admin a ready SQL script.

## 6. Data: Databricks

Databricks started from files and Spark rather than SQL tables. It's the lakehouse: one copy of the data in the client's own cloud storage, one guard for all access, and an AI platform on the same tables.

### Databricks — a warehouse, a workshop and a lab on one site

> A factory site: a cheap warehouse for raw goods, a workshop where they're cleaned and processed, a shop window for finished products, a lab for experiments — and one guard at the gate checking everyone's pass.

**Databricks** is a data platform built by the creators of Apache Spark. The company keeps all its data in cheap cloud file storage, processes it with **Spark** (a distributed engine for data too big for one machine), answers questions in SQL, and builds ML models and AI agents on the same data — all under one permission system, **Unity Catalog**. It runs on top of the client's cloud: AWS, Azure (as Azure Databricks) or GCP. People work in **notebooks** (like Jupyter, in the browser, always attached to compute) and **jobs**; analysts use SQL and **Genie**; AI work lives in **Agent Bricks**. Compute — **clusters** for Spark, **SQL warehouses** for SQL, **serverless** — is billed in **DBU** (Databricks Units). There's also **Lakebase**, a managed Postgres for apps that need fast reads and writes.

_Diagram: People and agents on top, compute in the middle, Unity Catalog guarding everything, and the data in the client's own storage._

#### Databricks (lakehouse platform · Azure Databricks)

- **What it is:** A lakehouse platform: files in the client's cloud storage, Spark and SQL on top, AI on the same tables.
- **Example:** A distributor keeps sales, inventory and CRM in gold tables `main.sales_gold.*` on Azure Databricks.
- **Catch:** Three clouds, three slightly different products: on Azure identity comes through Entra; feature availability (Lakebase, serverless) depends on cloud and region.
- **Related:** Tables are **Delta Lake**; rights are **Unity Catalog**; the agent queries a **SQL Warehouse**.

### Delta Lake — a folder of files that behaves like a table

> A warehouse logbook: the boxes on the shelves are just boxes, but the logbook at the door says which boxes make up today's stock. Change the logbook in one stroke — and the stock changes all at once.

**Delta Lake** is an open table format. Underneath it's ordinary **Parquet** files (a columnar file format) plus a `_delta_log` folder — a journal that records which files make up the table right now. Thanks to that journal, a plain folder of files gets the powers of a real database: **ACID transactions** (a write lands whole or not at all; readers never see half), a **schema** (you can't write a string into a number column), **time travel** (read the table "as it was yesterday"), and `MERGE`, `UPDATE`, `DELETE`. If you know Postgres: it's like the WAL, except the journal sits next to the files in S3 instead of inside a database server. Fabric uses the same format.

_Diagram: Plain Parquet files plus a transaction log. The log says which files are the table — and that turns a folder into a database table._

#### Delta Lake (Parquet + transaction log)

- **What it is:** An open table format: Parquet files plus a `_delta_log` journal that adds transactions and history.
- **Example:** The nightly job MERGEs new orders into `orders`; analysts never see a half-written table.
- **Catch:** It's a format, not a server: something still has to run compute to read it — and that compute is what you pay for (DBU).
- **Related:** The base of the **Lakehouse**; shared by **Databricks** and **Microsoft Fabric**.

### Unity Catalog — one guard with one logbook

> A guard at the only gate with a logbook: it doesn't matter whether you come on foot, by car or as a delivery robot — he checks your pass and writes down what you took.

**Unity Catalog** is the single layer of permissions and catalogue for all data and AI in Databricks; it's on by default for every workspace created after November 8, 2023. Names have three levels — `catalog.schema.table`, like `main.sales_gold.orders` — and the same scheme covers views, **volumes** (folders of files like PDFs), functions and models. Rights are granted with `GRANT` to people, groups and **service principals**. You can hide rows (**row filters**) and columns (**column masks**). **Lineage** draws where data came from and where it went, and every action is audited in **system tables**. Whether the request comes from a notebook, SQL, or your agent, it passes the same check. To read one table, a principal needs three grants at once: `USE CATALOG` + `USE SCHEMA` + `SELECT`.

_Diagram: Notebooks, SQL and agents all pass the same check. Unity Catalog grants access to tables, volumes and models — and logs it._

#### Unity Catalog (catalog.schema.table · GRANT · lineage)

- **What it is:** Databricks' central permissions, catalogue, lineage and audit for data and AI objects.
- **Example:** The agent's service principal gets `SELECT` on schema `main.sales_gold` and `READ VOLUME` on `main.docs.contracts` — nothing else.
- **Catch:** Missing one of the three grants looks like "table not found". Old workspaces may still keep tables in the legacy `hive_metastore` with old rules — check what was migrated.
- **Related:** Guards the **Delta Lake** tables; checked on every **SQL Warehouse** query.

### Medallion — bronze, silver, gold

> Ore from the mine, metal from the furnace, a finished ring in the shop window. The jeweller sells only the ring — but keeps the ore, in case the furnace has to run again.

**Medallion** isn't a product, it's the common way to lay data out in quality layers. **Bronze** — raw data exactly as it came from the source: duplicates, junk, mixed formats. You keep it so everything can be rebuilt. **Silver** — cleaned: correct types, no duplicates, tables linked by keys. **Gold** — aggregates and business tables: revenue by day, active customers. Reports and agents read gold. The pipelines that move data between layers are **Lakeflow Jobs** (formerly Workflows) and **Lakeflow Declarative Pipelines** (formerly Delta Live Tables, DLT). The rule for an AI project: the agent reads gold, sometimes silver, never bronze.

_Diagram: Sources → bronze (as it came) → silver (cleaned) → gold (ready for the business). The agent reads gold._

#### Medallion (bronze · silver · gold)

- **What it is:** Layering data by quality: raw (bronze), cleaned (silver), business-ready (gold).
- **Example:** The agent reads `main.sales_gold.orders`; the raw CRM dumps stay in bronze, out of its reach.
- **Catch:** Gold is refreshed nightly or hourly. The agent should say what date its numbers are from.
- **Related:** Built on **Delta Lake**; grant the agent gold only through **Unity Catalog**.

### SQL Warehouse and OAuth M2M — how the agent asks a question

> A self-service counter with a ticket machine: you show your ID once, get a ticket that's valid for an hour, and the clerk checks the list before handing anything over.

A **SQL warehouse** is Databricks compute made only for SQL; BI tools and your app connect to it by **server hostname** and **HTTP path** (both in the warehouse's Connection details). There are three types: **serverless** (recommended, usually starts in 2–6 seconds), **pro** and **classic** (around 4 minutes). The agent signs in as a **service principal** with **OAuth M2M** (machine-to-machine): it swaps `client_id` and `client_secret` for a short-lived token, then sends SQL. Unity Catalog checks the grants and filters; the engine reads only the needed files and columns; rows come back; and every query lands in the audit tables (`system.access.audit`). Pass values as query parameters (`:since`), not by gluing strings — even when an LLM writes the SQL — and always add a `LIMIT`.

_Diagram: The agent swaps its client ID and secret for a short token, sends SQL to the warehouse, Unity Catalog checks it, rows come back, and it's all audited._

#### SQL Warehouse (serverless · OAuth M2M · DBU)

- **What it is:** Databricks' SQL-only compute, which apps and the agent query with a service-principal token.
- **Example:** A small serverless warehouse just for the agent (`CAN USE` permission) — its costs are visible and it can have its own limit.
- **Catch:** A classic warehouse takes ~4 minutes to start, so the agent's first query times out — and the API creates classic by default. Personal access tokens (PAT) are often banned; use OAuth M2M.
- **Related:** Checked by **Unity Catalog**; the identity is a **Service Principal**; the design choice is **As the User vs As Itself** (U2M / on-behalf-of).

### Agent Bricks — Databricks' AI umbrella

> A shopping mall where every AI shop has moved under one roof and one sign — same shops as before, new name over the entrance.

Names changed most in this corner. **Mosaic AI** was the old umbrella name (after Databricks bought MosaicML); since March 2026 the umbrella for all AI is **Agent Bricks** — a platform to build and run agents. It supports frontier and open models (OpenAI, Anthropic, Gemini and others), frameworks like LangGraph, CrewAI and the Claude Agent SDK, tracing through **MLflow**, managed agent memory (on Lakebase), a sandbox for running code, and document parsing (`ai_parse_document`, `ai_extract`, `ai_classify`). Around it: **Model Serving** (a model as a REST endpoint, OpenAI-compatible for LLMs), **Unity AI Gateway** (one gate for model and MCP calls: rights, budgets, limits, PII protection, tracing), **Databricks Apps** (host your agent inside Databricks), **Genie** (ask the data in English, with a Genie MCP server). Vector search was renamed **AI Search** on June 1, 2026 and now adds full-text, hybrid and reranking; an index can stay in sync with a Delta table.

_Diagram: Models, frameworks, tracing, serving, the AI gateway, search, Genie and app hosting — all under Agent Bricks. Plus the old names you'll still hear._

#### Agent Bricks (formerly Mosaic AI · AI Search · Genie)

- **What it is:** Databricks' platform for building, running and governing agents next to the data.
- **Example:** Contracts parsed with `ai_parse_document` → a chunks table → an AI Search index that stays in sync with it; the agent's model calls go through Unity AI Gateway.
- **Catch:** Renames everywhere: DLT → Declarative Pipelines, Workflows → Lakeflow Jobs, Vector Search → AI Search, Delta Sharing → OpenSharing (June 2026). The client's docs use the old names — know both.
- **Related:** Snowflake's counterpart is **Cortex**; Fabric's is the **Data Agent**; Azure's is **Microsoft Foundry**.

> **The Databricks question:** "Does my agent read only gold tables, through a small serverless SQL warehouse, as a service principal with OAuth M2M and read-only grants in Unity Catalog — with every query in the audit tables?"

> Databricks is the lakehouse: Delta files in the client's storage, Unity Catalog as the one guard, gold tables for the agent, and a small serverless warehouse with OAuth — not personal tokens.

## 7. Data: Microsoft Fabric

Fabric is Microsoft's answer to Snowflake and Databricks: one product with storage, data loading, processing, Power BI and AI. Companies that already live in Microsoft pick it. The new ideas here are one store for the whole company and one shared capacity that everyone spends.

### Microsoft Fabric and OneLake — 'Office for data'

> Five storerooms in five buildings, each with its own key, replaced by one big building with one pass and one electricity bill.

**Microsoft Fabric** is an all-in-one SaaS data platform: one shared store (**OneLake**), data loading (**Data Factory**), processing (Spark, SQL), reports (**Power BI**) and AI (Copilot, data agents) — in one browser portal, signed in through Entra ID, paid for as one **capacity**. Before Fabric, a Microsoft shop glued together Azure Data Factory, ADLS, Azure Synapse and Power BI, each with its own bill, rights and network, copying data three or four times. **OneLake** is one logical store for the whole tenant, created automatically — Microsoft calls it "OneDrive for data". Inside are folders per **workspace** and **item**, with tables in Delta format (the same open format as Databricks); from outside it looks like ADLS Gen2. Workspace roles are **Admin**, **Member**, **Contributor**, **Viewer** — and you can also share a single item. In Power BI, the **semantic model** (formerly "dataset") is the business layer of tables, relationships and DAX measures — often where the company has already agreed what "revenue" means.

_Diagram: One Entra tenant, one paid capacity, workspaces full of items — and under it all, OneLake. Outside data comes in by shortcut or mirroring._

#### Microsoft Fabric (OneLake · workspace · item)

- **What it is:** Microsoft's all-in-one data platform with one store (OneLake) and one bill (capacity).
- **Example:** A clinic network mirrors its EHR and billing from Azure SQL into Fabric, reports in Power BI on an F64.
- **Catch:** Simpler than Databricks, but less control. And the names move: dataset → semantic model, "license mode" → "workspace type", P SKU → F SKU.
- **Related:** Paid through a **Capacity**; read through the **SQL Analytics Endpoint**; fed by **Shortcuts and Mirroring**.

### Capacity and F SKUs — one shared power bill

> The electricity contract for a whole office: if your new heater runs flat out, the lights flicker on the CFO's floor too.

A **capacity** is a pool of compute the company buys. Each workspace is attached to one capacity, and everything it does — SQL, Spark, report refreshes, Copilot — spends its **CU (capacity units)**. Sizes are **F SKUs**: F2, F4, F8 … F64 … F2048; the number is the CU count, and F64 matches the old Power BI Premium P1. It's bought in Azure, billed per second (minimum one minute) or reserved for a year at a discount; prices depend on the region, so check the Azure calculator for the client's region. A capacity can be paused — then nothing in it works. **F64 is a threshold**: from F64 up, people with a free licence can view Power BI reports; below it, every viewer needs Pro or PPU. Fabric lets a heavy job briefly take more than you bought (**bursting**) and spreads the cost over time (**smoothing**: interactive work over at least 5 minutes, background over 24 hours). Overdo it and **throttling** starts: after 10 minutes of "debt" interactive queries wait 20 seconds, after 60 minutes they're rejected, after 24 hours everything is rejected.

_Diagram: Everyone spends from one capacity. Short bursts above it are smoothed out; too much debt means delays, then rejections._

#### Capacity (F SKU · CU · throttling)

- **What it is:** The shared, pre-bought compute pool that every Fabric workspace attached to it spends.
- **Example:** An F64 serves the whole company; the agent's queries are kept small and watched in the Capacity Metrics app.
- **Catch:** Throttling isn't "a bit slower" — it's `CapacityLimitExceeded` errors for everyone. And if the client pauses capacity at night to save money, your agent doesn't work at night.
- **Related:** The bill of **Microsoft Fabric**; Snowflake's per-cluster **Virtual Warehouse** is the opposite model.

### SQL Analytics Endpoint — Fabric looks like SQL Server from outside

> A museum display case: you can look at every object from all sides as long as you like, but there's glass in front — nothing can be moved or added.

Fabric has two table homes. A **lakehouse** is for data engineers: Delta tables (`Tables` folder) plus any files (`Files` folder), written with Spark, notebooks and pipelines. A **warehouse** is for SQL people: tables only, with full **T-SQL** (Microsoft's SQL dialect) — `INSERT`, `UPDATE`, `MERGE`. Both are Delta in OneLake, and you can join them in one query. Every lakehouse (and mirrored database) automatically gets a **SQL analytics endpoint**: read-only T-SQL over its Delta tables. You can `SELECT`, create views and functions, and set row-level security — but not change data. From outside it looks like SQL Server: your agent connects with ODBC Driver 18 on port 1433 (TDS protocol) to an address like `xxxx.datawarehouse.fabric.microsoft.com`, with an Entra token for scope `https://database.windows.net/.default`. Read-only is a good thing for an agent.

_Diagram: Lakehouse vs warehouse at a glance. The agent reads a lakehouse through its read-only SQL endpoint, like any SQL Server._

#### SQL Analytics Endpoint (lakehouse vs warehouse · T-SQL)

- **What it is:** The automatic, read-only SQL Server-style endpoint over a Fabric lakehouse or mirrored database.
- **Example:** `pyodbc` + an Entra token → `SELECT TOP (100) clinic, COUNT(*) … FROM dbo.appointments` with parameters.
- **Catch:** Only tables in `/Tables` show up, new ones after a metadata sync (sometimes with a delay). You can't write agent logs or cache there — use a warehouse, SQL database in Fabric, or your own DB.
- **Related:** Spends the **Capacity**; access needs a workspace role or item permission for the **Service Principal**.

### Shortcuts and Mirroring — data without building ETL

> A shortcut on your desktop opens a file that lives somewhere else. Mirroring is a copy of that file that updates itself every time the original changes.

Fabric's way to avoid copy pipelines. A **shortcut** is like a symlink: a folder in a lakehouse that really points at S3, ADLS, Google Cloud Storage, Dataverse, SharePoint/OneDrive or another OneLake item. No data is copied; delete the shortcut and the source is untouched. For internal shortcuts, access is checked with the identity of whoever reads. **Mirroring** is a continuous copy: Fabric keeps a database replicated into OneLake as Delta, close to real time. Sources include Azure SQL, SQL Server, Azure Database for PostgreSQL, Cosmos DB, Snowflake, Google BigQuery, Oracle and SAP. For Azure Databricks there's metadata mirroring: only the catalogue is copied, and data is read through shortcuts. Replication compute is free, and storing replicas is free up to 1 TB per CU of capacity.

_Diagram: A shortcut points at data where it already lives. Mirroring keeps a near-real-time Delta copy in OneLake._

#### Shortcuts and Mirroring (symlink · live copy)

- **What it is:** Two ways to bring outside data into OneLake: point at it (shortcut) or keep a live copy (mirroring).
- **Example:** Billing tables from Azure SQL are mirrored into Fabric; the agent reads them via the mirrored database's SQL endpoint.
- **Catch:** Paused capacity stops mirroring too. Shortcut names can't have spaces or non-Latin characters.
- **Related:** Lands data in **Microsoft Fabric**'s OneLake; mirrored databases get a **SQL Analytics Endpoint**.

### Fabric Data Agent — a ready 'chat with your data'

> A reference librarian who knows the catalogue by heart and fetches answers for you — but only from the shelves your library card opens, and never lets you write in the books.

A **Fabric data agent** is a configurable "chat with data". You pick up to five sources — lakehouse, warehouse, semantic model, KQL database, mirrored database, ontology — write instructions and example question → query pairs, and the agent turns a question into SQL, DAX or KQL and runs it. It's generally available. It's **read-only** and works **as the user**: it sees only what that person may see. You can call it from Microsoft 365 Copilot, Copilot Studio, Teams, Microsoft Foundry, or as an MCP server. **Fabric IQ** is a newer "business meaning" layer (ontology, semantic models, data agents) for outside agents; in Foundry Agent Service the old "Fabric data agent" tool will be retired on November 6, 2026 in favour of Fabric IQ. **Copilot in Fabric**, the built-in helper, now works on any paid capacity from F2 (the F64 requirement was dropped in April 2025) — but not on trial capacity.

_Diagram: Called from Teams, Copilot, Foundry or MCP; turns a question into SQL, DAX or KQL over up to five sources — read-only, as the user._

#### Fabric Data Agent (Fabric IQ · Copilot)

- **What it is:** Fabric's built-in, read-only question-to-query agent over chosen sources, acting as the user.
- **Example:** Path A for a "why are no-shows rising in Austin?" agent: a data agent over the semantic model, published to Teams — user rights apply by themselves.
- **Catch:** English only, you can't choose the LLM, answers capped at 25 rows × 25 columns, no PDFs, and the source and agent must be in the same capacity region. Need more control? Build your own agent on the SQL endpoint (path B).
- **Related:** The Fabric cousin of **Cortex** and **Agent Bricks**; path B uses the **SQL Analytics Endpoint**.

> **The Fabric question:** "Has the Fabric admin allowed service principals, does my principal have the smallest role on one item, are the agent's queries small enough for a shared capacity — and would a data agent on their semantic model already do the job?"

> Fabric is Microsoft's data platform in one box: OneLake for storage, one shared capacity for compute, a read-only SQL endpoint for your agent — and a built-in data agent when the simple path is enough.

## 8. Putting it together

Now the real job: an AI agent inside a client company. Every system above asks the same few questions — who is the agent, what may it read, as whom does it act, and can the security team sign off. Answer them early and the project moves; answer them late and it waits.

### The blueprint: one agent, three layers

> Moving into an office building as a new tenant: you get badges from the front desk, a unit from the landlord, and a key to just your shelf in the archive — all arranged before the moving truck arrives.

A typical project, in plain words. The client's data lives in Snowflake (or Databricks, or Fabric). Employees sign in through Entra ID (or Okta). The app runs in the client's cloud — often Azure. Your agent lets in only "their people" through their own sign-in, with app roles their IT assigns to groups. It runs as a Container App with a managed identity, calls a model deployment in Foundry, reads secrets from Key Vault, and sits behind private endpoints if security asks. It reads data with the smallest rights: a Snowflake service user with a key and a read-only role, a Databricks service principal with OAuth M2M and gold-only grants, or a Fabric service principal with Viewer on one item. Logs go to Application Insights — without personal data in the prompts. Deploys come from GitHub with OIDC, no secrets in the repo.

_Diagram: Sign-in through the client's IdP, the agent in their Azure with a managed identity, and one narrow connection to the data platform._

### Least Privilege — only what the job needs

> A hotel cleaner's key card opens the rooms on her floor during her shift — not the safe, not the manager's office, not the other floors.

**Least privilege** means giving only the minimum rights needed, on the smallest scope, read-only by default. Each system has its version: Contributor on one resource group instead of the whole subscription; a role like `AI_AGENT_RO` with `SELECT` on views instead of anything near `ACCOUNTADMIN`; delegated `Files.Read.All` instead of application `Sites.Read.All`; Viewer on one Fabric item instead of Admin on the workspace; gold schema only in Unity Catalog. It matters even more for agents than for people: an LLM can be tricked by a prompt injection, and when it is, the damage stops exactly at what it was allowed to do.

_Diagram: The same four systems: too much on the left, just enough on the right._

#### Least Privilege (minimal rights · smallest scope)

- **What it is:** Granting only the rights a job needs, on the narrowest scope, for as short as possible.
- **Example:** The agent's Snowflake role can read three views in `SALES.MART` and nothing else — not even the raw tables behind them.
- **Catch:** Too narrow and the agent fails in odd ways ("table not found"). Start minimal, add rights one by one, and write down why each exists.
- **Related:** Shapes **Resource Hierarchy** roles, **Roles and RBAC**, **Unity Catalog** grants; the first thing the **Security Review** checks.

### As the User vs As Itself — whose eyes the agent sees with

> Sending your assistant to the archive with your own library card, versus with the building's master card. With yours, she can only bring back what you could. With the master card, she can bring back anything — and you have to decide what she shows to whom.

This is the biggest design choice, and every security review asks about it. **As the user**: the agent calls the data source with the signed-in person's identity — delegated permissions in Entra, on-behalf-of, OAuth U2M in Databricks, sign-in via Okta or Entra to Snowflake, the Fabric data agent. The source applies each person's own rights, so Anna sees Texas and Ben sees Ohio, for free. **As itself**: the agent uses one **service account** — a service principal, a managed identity, a Snowflake service user, "an account for a program, not a person". Everyone who talks to the agent sees the same data, so _you_ must filter: row access policies in Snowflake, row filters in Unity Catalog, RLS in Fabric, or your own code. Rule of thumb: answering people → act as the user; background jobs like nightly indexing → a small service identity.

_Diagram: As the user: each person's own rights apply. As itself: one identity sees everything, and the filtering is on you._

#### As the User vs As Itself (delegated / OBO vs service account)

- **What it is:** The choice between the agent acting with each user's identity or with its own service identity.
- **Example:** The contract assistant searches SharePoint as the user; a separate background indexer runs as a service identity with a small set of application permissions.
- **Catch:** For medical or other sensitive data this is the key review question. With one shared identity, be ready to show exactly how rows are filtered.
- **Related:** Built from **Delegated vs Application Permissions**, **Cross App Access**, **Service User**; a core **Security Review** question.

### Security Review — the exam before launch

> A building inspection before opening day: the inspector walks through with a checklist, and the doors open only after the last box is ticked.

A **security review** is the client's security team checking your solution before it goes live. The questions are predictable, so prepare the answers — ideally a short document listing every connection. Where does the data go, which region runs the model, which LLM under which contract (data residency)? Are there any API keys? The right answer is "none — managed identity, secrets in Key Vault". Are services closed to the internet? Are the roles minimal? Does the agent act as the user or as itself, and who sees what? What can it _do_ by itself — write, delete, send email — and is there human confirmation? What goes into the logs, for how long, and is there personal data in prompts? How do we revoke access — disable a user, delete the enterprise app — and does it work immediately? Defences against prompt injection and content filters come up too.

_Diagram: Eight questions every security team asks. Have the answers written down before they ask._

#### Security Review (the client's sign-off)

- **What it is:** The client security team's check of data flows, identities, rights, logs and revocation before launch.
- **Example:** You bring a one-page map: every connection, its identity, its role, and why it's needed — plus the audit tables that show every query.
- **Catch:** Application-wide read permissions (`*.Read.All`) scare reviewers most. Expect to justify each one, or replace it with delegated access.
- **Related:** Checks **Least Privilege**, **As the User vs As Itself**, **Private Endpoint**, **Key Vault**.

### Day-One Access — start the slow part first

> Ordering a custom-made suit for a wedding: the fitting takes weeks, so you order it the day you get the invitation, not the week before.

In a mid-market company, access is usually the slowest part of the whole project. A guest account, a role on a resource group, an app registration with admin consent, a Snowflake service user, Unity Catalog grants, the Fabric tenant setting "Service principals can call Fabric public APIs" — each is a ticket to a different admin, and together they can take one to three weeks. You are not the admin, and you won't be. So on day one, send one message with everything: redirect URIs, scopes, app roles, groups, grants — and why each is needed. For Snowflake, send a ready SQL script the admin just runs. Ask for the preview/test environment first. And check the model quota in the right region before you build, not on demo day.

_Diagram: Send the full list on day one and the access is ready when the build is. Ask in week three and the demo waits for a role._

#### Day-One Access (the access list)

- **What it is:** The habit of requesting every account, role and setting at the very start, in one precise list.
- **Example:** Day 1: guest + Contributor on `rg-ai-agent-dev`, app registration details, `SVC_AI_AGENT` script, Fabric admin contact, quota check.
- **How to avoid:** Find each admin early — the Fabric admin is often not the Azure admin. Track requests like tasks, with owners and dates.
- **Related:** The practical side of **Least Privilege**; feeds the **Security Review**.

### How it all connects

> A jigsaw: each piece means little alone; together they make the picture.

The concepts in this course are one system. The **cloud** branch — Azure's **resource hierarchy**, **managed identity**, **Key Vault**, **private endpoints** and **Foundry** — answers _where the agent runs and how it holds no secrets_. The **identity** branch — **IdP and SSO**, **OIDC**, **Entra ID** with **app registrations**, **permissions**, **app roles** and **Conditional Access**, **Okta** with **SCIM** and **Cross App Access**, and **Agent ID** — answers _who the agent and its users are_. The **data** branch — from **lake** to **lakehouse**, **Snowflake**, **Databricks**, **Fabric** — answers _what the agent may read_. All three meet in your agent, held together by **least privilege**, the choice of acting **as the user or as itself**, and the **security review**.

_Diagram: Three branches — cloud, identity, data — meet in your agent, held together by least privilege and the security review._

#### Before you start an AI project inside a client

- **Who are the admins** — Azure, Entra or Okta, the data platform, Fabric — and have I sent each one the exact list?
- **Where does the agent run** — a Container App with a managed identity, roles on one resource group?
- **How do people sign in** — OIDC through the client's IdP, app roles or filtered groups, stable user IDs?
- **As the user or as itself** — and if as itself, how are rows filtered?
- **What does it read** — gold tables or views only, read-only, through a small compute that sleeps?
- **What will security ask** — keys, network, roles, logs, data residency, revocation — and are my answers written down?

#### The words you now own

- **Tenant, subscription, resource group** — and why a role on one RG beats one on the subscription.
- **Managed identity, Key Vault, private endpoint** — an app with no keys, behind no public door.
- **IdP, SSO, OIDC, SAML** — and why you key users by `oid` + `tid` or `sub`, not email.
- **App registration vs service principal**, **delegated vs application permissions**, **admin consent**.
- **App roles, Conditional Access, Microsoft Graph, Entra Agent ID**.
- **Okta org, Universal Directory, SCIM, org vs custom authorization server, Cross App Access**.
- **Data warehouse, data lake, lakehouse, Delta Lake, medallion**.
- **Virtual warehouse, credits, service user, Cortex**; **Unity Catalog, SQL warehouse, OAuth M2M, Agent Bricks**.
- **OneLake, capacity, F SKU, SQL analytics endpoint, shortcut, mirroring, data agent**.
- **Least privilege, service account, security review**.

## Cheat sheet: all 42 concepts

### The map

- **Enterprise Stack** (cloud · identity · data): Three layers in every big company; your agent sits between them.

### Cloud: Azure

- **Microsoft Azure** (Microsoft's cloud): Familiar cloud ideas, different names; picked because "everything is Microsoft".
- **Resource Hierarchy** (tenant · subscription · RG): Nested folders; a role given above applies to everything below.
- **Container Apps** (App Service · AKS · Functions): Serverless containers — the usual home for an agent backend.
- **Managed Identity** (no password): An app account that gets tokens from Entra; nothing to leak.
- **Key Vault** (secrets safe): Where the few real secrets live, read with a narrow role.
- **Private Endpoint** (VNet): A private IP for a service, so it can be closed to the internet.
- **Microsoft Foundry** (formerly Azure AI Foundry): Model deployments, agents and evals inside the client's tenant.

### Identity: Entra ID

- **Identity Provider** (IdP · SSO): The company's front desk; one work account opens every app.
- **OIDC and SAML** (auth code + PKCE): How apps sign people in through the IdP; OIDC for new code.
- **Microsoft Entra ID** (formerly Azure AD): Microsoft's cloud directory of people, groups and apps.
- **App Registration vs Service Principal** (Enterprise app): The app's passport, and its copy in a tenant that holds the rights.
- **Delegated vs Application Permissions** (consent): Act as the user, or as the app itself with admin consent.
- **App Roles** (roles claim): Your roles, assigned by their IT to groups, checked by your backend.
- **Conditional Access** (MFA rules): If-then rules at every sign-in; needs Entra ID P1.
- **Microsoft Graph** (graph.microsoft.com): One API to Microsoft 365 data, bounded by the token's scopes.
- **Entra Agent ID** (agent blueprint): An identity type for AI agents, governed like an employee.

### Identity: Okta

- **Okta** (Workforce Identity): The neutral IdP for mixed-vendor companies; an org per company.
- **SCIM** (joiner–mover–leaver): The IdP creates and switches off users in your app automatically.
- **Authorization Server** (org vs custom): Org for sign-in; custom for your own API's scopes.
- **Cross App Access** (XAA · Agent SSO): Agents get short, logged tokens to other apps through Okta.

### Data: Snowflake

- **Warehouse · Lake · Lakehouse** (three shapes): Strict tables, raw files, or files with table rules on top.
- **Snowflake** (cloud data warehouse): SQL analytics with storage and compute split.
- **Virtual Warehouse** (credits): A compute cluster billed per second; set auto-suspend to 60.
- **Roles and RBAC** (AI_AGENT_RO): Grants go to roles, roles go to users; views only for the agent.
- **Service User** (TYPE = SERVICE): A program's account; key pair or OAuth, passwords blocked.
- **Cortex** (AI next to the data): LLM functions, text-to-SQL, search and agents inside Snowflake.

### Data: Databricks

- **Databricks** (lakehouse platform): Files in the client's storage; Spark, SQL and AI on the same tables.
- **Delta Lake** (Parquet + log): A folder of files that behaves like a transactional table.
- **Unity Catalog** (one guard): Grants, masks, lineage and audit for every way in.
- **Medallion** (bronze · silver · gold): Quality layers; the agent reads gold.
- **SQL Warehouse** (OAuth M2M): SQL compute; serverless starts in seconds, classic in minutes.
- **Agent Bricks** (formerly Mosaic AI): Databricks' AI umbrella: models, serving, gateway, AI Search, Genie.

### Data: Fabric

- **Microsoft Fabric** (OneLake): One store and one bill for all of Microsoft's data tools.
- **Capacity** (F SKU · CU): A shared compute pool; overspend leads to throttling.
- **SQL Analytics Endpoint** (read-only T-SQL): A lakehouse seen as SQL Server; ideal for an agent's reads.
- **Shortcuts and Mirroring** (no ETL): Point at outside data, or keep a live copy in OneLake.
- **Fabric Data Agent** (Fabric IQ): A built-in read-only "chat with data" that acts as the user.

### Putting it together

- **Least Privilege** (minimal rights): Only what the job needs, on the smallest scope.
- **As the User vs As Itself** (OBO vs service account): Each user's rights, or one identity whose output you filter.
- **Security Review** (client sign-off): Predictable questions; have the answers written down.
- **Day-One Access** (the access list): Request everything on day one, in one precise message.

> An AI agent inside a company is mostly an access project. Run it in their cloud with no keys, sign people in through their IdP, read the smallest slice of data, and ask for everything on day one.

End of express course · 8 chapters · 42 concepts

Next comes practice: take a free Azure account and deploy a tiny Container App with a user-assigned managed identity that reads one secret from Key Vault — no keys anywhere. Register an app in an Entra test tenant (or an Okta developer org), sign in with OIDC, and check the ID token by hand. Then open a Snowflake trial, create a `TYPE = SERVICE` user with a key pair and a read-only role, and query a view from Python. Write down every grant you needed and why — that list is your first security-review document. Hold one idea above the rest: the enterprise stack is just three questions — where does it run, who is it, what may it read — and the best answers are always the smallest ones.
