Security & Authentication
This is one of the most heavily tested topics in the entire AI-102 exam. Security questions appear in every domain — not just Part 1. Master this topic once and you'll gain marks across all 6 parts. We cover every authentication method, RBAC roles, Key Vault, private endpoints, network security, and encryption.
This topic uses: API key, endpoint, resource, resource group, subscription, SDK, environment variable, and pip install from the previous topics. It introduces entirely new security concepts on top of that foundation.
Security terms you must know
All of these appear in exam questions. Learn them before the concepts below use them.
Proving who you are. When your Python code calls an Azure AI service, it must prove it's authorised to do so. Authentication is the "who are you?" check. There are multiple ways to authenticate — this topic covers all of them.
Deciding what you're allowed to do after you've proven who you are. Authentication = proving identity. Authorisation = determining permissions. In Azure, RBAC (Role-Based Access Control) handles authorisation.
The new name for Azure Active Directory (Azure AD). Microsoft's cloud identity service — the system that manages users, groups, and application identities in Azure. If you see "Azure AD" in an exam question, it means Microsoft Entra ID.
An identity in Microsoft Entra ID that Azure automatically creates and manages for a resource (like a Virtual Machine, App Service, or Function). The resource can use this identity to authenticate to other Azure services without storing any credentials in code. Think of it as Azure giving your resource an automatic ID card.
A managed identity that is tied directly to one specific Azure resource. When that resource is deleted, the identity is automatically deleted too. One resource = one identity. Simpler to set up.
A managed identity that exists independently of any single resource. You create it separately and then assign it to one or more resources. When a resource is deleted, the identity still exists. Use when multiple resources need to share the same identity.
An application identity in Microsoft Entra ID — like a user account but for an application rather than a person. Used when code running outside Azure (e.g. on your laptop or in GitHub Actions) needs to authenticate to Azure services.
Azure's permission system. You assign a role (a set of permissions) to a principal (a user, group, or identity) at a specific scope (subscription, resource group, or resource). This determines what actions that principal can perform.
A secure cloud storage service for secrets (API keys, passwords), keys (encryption keys), and certificates (SSL/TLS). Instead of storing an API key in your code or an environment variable, you store it in Key Vault and your code retrieves it securely at runtime.
A network interface that connects your Azure AI resource to your private Virtual Network (VNet). Once a private endpoint is configured, the resource is no longer accessible from the public internet — it can only be reached from within your VNet. Requires S0 pricing tier (not available on F0).
Azure's private network. Similar to your office network but in the cloud. Resources inside a VNet can communicate with each other privately. You can connect your on-premises network to a VNet using VPN or ExpressRoute to extend your corporate network into Azure.
By default, Azure encrypts your data using Microsoft-managed keys. Customer-Managed Keys let you use your own encryption keys stored in Azure Key Vault. You control the keys — meaning you control access to the encrypted data. Required for some compliance frameworks.
A security principle: give any user, application, or service only the minimum permissions it needs to do its job — no more. If an app only needs to read from an AI service, don't give it the Owner role. Give it only the Cognitive Services User role.
The practice of regularly replacing API keys to limit the damage if a key is ever leaked. Azure AI services give you two keys (Key1, Key2) specifically to enable zero-downtime rotation: switch apps to Key2, regenerate Key1, switch apps back to Key1.
Three layers of security you need to understand
Azure AI security works in three independent layers. The exam tests all three separately and in combination. Understand each layer clearly before diving into the details.
Imagine your Azure AI resource is a bank vault full of sensitive data.
Layer 1 — Authentication is the security guard at the door who checks
your ID before letting you in. This is who you are.
Layer 2 — Authorisation (RBAC) is the list on the guard's clipboard
that says what each person is allowed to do inside the vault —
some people can only view, others can also add, some can delete.
This is what you can do.
Layer 3 — Network Security is the physical perimeter —
the walls, private road, and gate around the bank building.
Even if you have valid ID and permissions, you can't get in
unless you're physically on the right network. This is
where you can connect from.
Authentication
API keys · Entra ID tokens · Managed Identity · Service Principals
Authorisation
RBAC roles · Scope · Least privilege
Network Security
Private endpoints · VNet · IP firewall rules · Custom domain
Four ways to authenticate to an Azure AI service
The exam presents scenarios and asks which authentication method is most appropriate. Each method has a specific use case. Learn the pattern for each.
The simplest method. Your Azure AI resource gives you two keys:
Key1 and Key2. You include one of these keys in every API request
in a header called Ocp-Apim-Subscription-Key.
Azure validates the key and grants access.
You have two keys so you can rotate them without downtime:
switch to Key2, regenerate Key1, switch back to Key1.
Instead of a static key, you request a temporary token from
Microsoft Entra ID (formerly Azure AD). This token is valid for
a short time (usually 1 hour) and then expires. It is included
in the request header as Authorization: Bearer <token>.
This is more secure than API keys because tokens expire
automatically and can be revoked instantly.
The most recommended method for Azure-to-Azure authentication.
Your Azure resource (e.g. App Service, Function, VM) gets an
automatic identity managed by Azure. It uses that identity to
get Entra ID tokens automatically — no credentials
stored anywhere in your code or configuration.
System-assigned: one-to-one with the resource, deleted when resource is deleted.
User-assigned: independent, can be shared across multiple resources.
An application identity registered in Microsoft Entra ID.
Used when code runs outside Azure — on a developer's
laptop, in a GitHub Actions pipeline, or on an on-premises server —
and needs to authenticate to Azure services.
You create a service principal, give it a client ID and a secret
(or certificate), and use those to get an Entra ID token.
Python code for each authentication method
The simplest method — you learned this pattern in Topic 1.
Using the API key directly with AzureKeyCredential.
# Import modules (from Topic 1 and Topic 2)
import os
from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential
# Read key and endpoint from environment variables (never hard-code!)
key = os.environ.get("LANGUAGE_KEY")
endpoint = os.environ.get("LANGUAGE_ENDPOINT")
# AzureKeyCredential wraps your key into the format Azure expects
credential = AzureKeyCredential(key)
# Create the client using API key authentication
client = TextAnalyticsClient(endpoint=endpoint, credential=credential)
print("Authenticated with API Key ✅")
The recommended production method. Notice there is no key or secret
anywhere in this code — Azure handles authentication automatically.
Requires pip install azure-identity.
# azure-identity provides credential classes for all Entra ID-based authentication
# Install with: pip install azure-identity
from azure.identity import DefaultAzureCredential
# The Language SDK — same as before
from azure.ai.textanalytics import TextAnalyticsClient
import os
endpoint = os.environ.get("LANGUAGE_ENDPOINT")
# DefaultAzureCredential is a "smart" credential that tries multiple methods
# in order until one works:
# 1. Environment variables (for service principal)
# 2. Managed Identity (when running inside Azure)
# 3. Azure CLI credentials (when running locally as a developer)
# This makes it work in both development (your laptop) AND production (Azure)
credential = DefaultAzureCredential()
# Pass the credential to the client — the SDK handles getting the token automatically
# No key needed — Azure fetches and refreshes the token behind the scenes
client = TextAnalyticsClient(endpoint=endpoint, credential=credential)
print("Authenticated with Managed Identity / DefaultAzureCredential ✅")
# ── For EXPLICIT managed identity (user-assigned) ─────────────────────
from azure.identity import ManagedIdentityCredential
# If you have a user-assigned managed identity, specify its client ID
# client_id is the unique identifier of the user-assigned managed identity
# (found in Azure portal → Managed Identities → your identity → Overview)
user_assigned_credential = ManagedIdentityCredential(
client_id="your-managed-identity-client-id-here"
)
client_explicit = TextAnalyticsClient(endpoint=endpoint, credential=user_assigned_credential)
print("Authenticated with User-Assigned Managed Identity ✅")
Getting an Entra ID token manually and using it in a REST API call. The exam may show raw HTTP requests — this is what they look like.
# This example shows how Entra ID tokens work at the HTTP level
# The SDK does all this automatically — but the exam may show raw HTTP requests
import requests # HTTP library — install with: pip install requests
# ── Step 1: Get a token from Microsoft Entra ID ───────────────────────
# Your Azure tenant ID — found in Azure portal → Entra ID → Overview
tenant_id = "your-tenant-id"
# The token endpoint for your tenant — this is always this format
token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
# The "scope" tells Entra ID which Azure service you want to access
# For Azure Cognitive Services / AI Services, the scope is always this URL
token_data = {
"grant_type": "client_credentials", # We're authenticating as an app, not a user
"client_id": "your-service-principal-client-id",
"client_secret": "your-service-principal-secret",
"scope": "https://cognitiveservices.azure.com/.default"
}
# POST request to get the token — Entra ID responds with a JSON object
token_response = requests.post(token_url, data=token_data)
# Extract the access_token from the JSON response
# .json() converts the response body from text into a Python dictionary
# ["access_token"] retrieves the value stored under that key in the dictionary
access_token = token_response.json()["access_token"]
# ── Step 2: Use the token in an API call ──────────────────────────────
# The token goes in the "Authorization" header with the word "Bearer " before it
# "Bearer" is a token type — it just means "the holder of this token is authorised"
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
# Now make the actual API call with the token in the header
endpoint = "https://your-resource.cognitiveservices.azure.com/"
response = requests.post(
f"{endpoint}text/analytics/v3.1/languages",
headers=headers,
json={"documents": [{"id": "1", "text": "Hello world"}]}
)
print(response.json()) # Print the API response
Service principal authentication — for code running outside Azure.
Uses ClientSecretCredential from azure-identity.
import os
from azure.identity import ClientSecretCredential
from azure.ai.textanalytics import TextAnalyticsClient
# Three pieces of information identify a service principal:
# 1. tenant_id — the unique ID of your Azure organisation (tenant)
# Found in: Azure portal → Microsoft Entra ID → Overview → Tenant ID
tenant_id = os.environ.get("AZURE_TENANT_ID")
# 2. client_id — the unique ID of the registered application (service principal)
# Found in: Azure portal → Entra ID → App Registrations → your app → Application ID
client_id = os.environ.get("AZURE_CLIENT_ID")
# 3. client_secret — a password generated for the service principal
# Found in: App Registrations → your app → Certificates & secrets
# ⚠️ Store this in an environment variable or Key Vault — never in code!
client_secret = os.environ.get("AZURE_CLIENT_SECRET")
endpoint = os.environ.get("LANGUAGE_ENDPOINT")
# ClientSecretCredential uses the three values to get an Entra ID token automatically
credential = ClientSecretCredential(
tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret
)
# Pass the credential to the client — same as managed identity from here on
client = TextAnalyticsClient(endpoint=endpoint, credential=credential)
print("Authenticated with Service Principal ✅")
Who can do what — the role table
Once someone is authenticated, RBAC determines what they're allowed to do. The exam tests specific roles for Azure AI resources — especially the critical trap around Owner and Contributor.
This catches many candidates. In Azure AI services, Owner and Contributor roles let you manage the resource (create it, delete it, change settings) but they do NOT grant access to call the service's endpoint (the AI functionality itself). To call the endpoint, you need Cognitive Services User role or to use an API key. This is different from most other Azure services.
1. Go to your AI resource in the Azure portal
2. In the left menu click Access control (IAM)
3. Click + Add → Add role assignment
4. Select the role → Next
5. Select the user, group, or managed identity → Next → Review + assign
The scope of the assignment matters: assigning at resource group level
gives access to all resources in that group.
Assigning at resource level gives access only to that specific resource.
Storing and retrieving secrets securely
In Topic 2, you learned to store your API key in an environment variable. For production, the better approach is Azure Key Vault — a dedicated cloud service for storing secrets, keys, and certificates.
An environment variable is like writing your PIN on a sticky note inside your desk drawer — safer than a public whiteboard, but still vulnerable if someone gets into your desk. Azure Key Vault is like a bank's safe deposit box: locked, audited, and only accessible to people with the right key card. Even if your application server is compromised, the attacker can't get to your secrets without also compromising the Key Vault access policies.
Key Vault concepts you must know
Secrets — Text values like API keys, connection strings, passwords.
Keys — Cryptographic keys used for encryption/decryption. Used for Customer-Managed Keys (CMK).
Certificates — SSL/TLS certificates for securing web endpoints.
Microsoft's best practice: use a separate Key Vault for each application. This limits the "blast radius" — if an attacker gains access to one vault, they can only reach that application's secrets, not secrets from all your applications.
Your application (running in Azure) should access Key Vault using its managed identity — not another set of credentials. This creates a chain: app → managed identity → Key Vault → secret. No credentials stored anywhere.
Soft delete: deleted secrets are retained for 90 days
before permanent removal — accidental deletion recovery.
Purge protection: prevents anyone (including admins)
from permanently deleting a vault during the retention period.
Required for Customer-Managed Keys compliance.
Python — Reading a secret from Key Vault
A new Python concept here: chaining methods.
When you call client.get_secret("name"), it returns an object.
You then use .value on that object to get the actual secret text.
This is explained in the code comments.
Requires: pip install azure-keyvault-secrets azure-identity
# Install these first:
# pip install azure-keyvault-secrets azure-identity
import os
from azure.keyvault.secrets import SecretClient # SDK for reading Key Vault secrets
from azure.identity import DefaultAzureCredential # From Topic 3 Section 3
# ── Your Key Vault URL ────────────────────────────────────────────────
# Format is always: https://YOUR-VAULT-NAME.vault.azure.net/
# Found in: Azure portal → Key Vault → Overview → Vault URI
vault_url = os.environ.get("KEY_VAULT_URL") # e.g. "https://myvault.vault.azure.net/"
# ── Authenticate using Managed Identity (no credentials in code!) ─────
# DefaultAzureCredential automatically uses the managed identity of the
# Azure resource this code is running on (App Service, VM, Function, etc.)
credential = DefaultAzureCredential()
# ── Create the Key Vault client ───────────────────────────────────────
# SecretClient is specifically for reading/writing secrets (not keys or certs)
# vault_url tells it which Key Vault to connect to
# credential tells it how to prove it has access
secret_client = SecretClient(vault_url=vault_url, credential=credential)
# ── Retrieve a secret ─────────────────────────────────────────────────
# get_secret("name") fetches the secret object from Key Vault
# The name must match the secret name you created in Key Vault
secret_object = secret_client.get_secret("language-api-key")
# The secret object has a .value property that holds the actual secret text
# (The object also has .name, .id, .properties for metadata — but we want .value)
api_key = secret_object.value
print(f"Secret retrieved successfully. Key starts with: {api_key[:4]}...")
# We only print the first 4 characters — never print a full key!
# ── Now use the key to call the AI service ────────────────────────────
from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential
endpoint = os.environ.get("LANGUAGE_ENDPOINT")
# Use the key we retrieved from Key Vault — not from an env variable
ai_credential = AzureKeyCredential(api_key)
ai_client = TextAnalyticsClient(endpoint=endpoint, credential=ai_credential)
print("AI client created using key from Key Vault ✅")
Customer-Managed Keys (CMK) — what the exam tests
By default Azure encrypts your data with Microsoft-managed keys. Customer-Managed Keys let you use your own keys stored in Key Vault. The exam tests the configuration requirements — not the Python code.
| CMK Requirement | Why it matters |
|---|---|
| Store the key in Azure Key Vault | CMK keys must live in Key Vault — Azure Managed HSM or standard Key Vault. |
| Provide the Key Identifier URI | You give Azure AI service the URI of your key so it can find and use it for encryption. |
| Grant the AI service access to Key Vault | The AI service's managed identity must have Key Vault Crypto User role on the vault. |
| Enable Soft Delete + Purge Protection on the vault | Required by Microsoft for CMK vaults — prevents accidental permanent deletion of encryption keys. |
The exam asks: "Which of the following is NOT required when configuring Customer-Managed Keys?" The wrong answers typically include: "disable Soft Delete on the Key Vault" (wrong — you must ENABLE it), or "Azure Managed HSM is required" (wrong — standard Key Vault works). The correct requirements are: Key Vault URI, create/import the key, grant the AI service access, and enable Soft Delete + Purge Protection.
Controlling where your AI service can be accessed from
Even with authentication and RBAC in place, you can add a third layer of security by restricting which networks can even reach your service. Think of this as controlling the physical perimeter.
Three network access modes
Note: requires S0 tier. Does NOT require a custom domain (unlike private endpoints).
Requirements:
• S0 tier (not available on F0)
• An Azure Virtual Network must exist
• DNS must be configured so requests to your endpoint URL resolve to the private IP
• For Azure AI Speech specifically: a custom subdomain must be enabled on the resource before creating a private endpoint. This is a Speech-specific requirement.
How to create: Azure portal → your resource → Networking → Private endpoint connections → + Private endpoint
"A company requires that the AI service must not be accessible from the public internet and all traffic must stay within the Azure Virtual Network."
→ Answer: Private endpoint on S0 tier
"A company wants to restrict their AI service to only be accessible from their corporate network (IP range 10.0.0.0/8)."
→ Answer: Selected Networks with IP firewall rule
"A developer needs to use a private endpoint with the Azure AI Speech service."
→ Answer: First enable a custom subdomain on the Speech resource, then create the private endpoint
Zero-downtime key rotation
API keys should be rotated regularly — replaced with a new key to limit the damage if a key is ever compromised. Azure gives you two keys (Key1 and Key2) specifically to enable this without any downtime.
Update your apps, environment variables, or Key Vault secret to use Key2 instead of Key1. Deploy the changes. All traffic now uses Key2.
In the Azure portal → your resource → Keys and Endpoint → click ↻ Regenerate Key1. Azure creates a new, completely different Key1 value. The old Key1 is immediately invalidated. Your apps are unaffected because they're using Key2.
Update your apps to use the new Key1 value. Now Key2 is unused and ready for the next rotation cycle.
For maximum security, also regenerate Key2 so both keys are fresh. Repeat this entire cycle periodically (monthly or quarterly is common).
Regenerating a key via the REST API (what the exam shows)
The exam sometimes shows a raw HTTP request for key regeneration and asks what it does. Know this pattern:
# This is a REST API call (not Python) — it regenerates a key via the Azure Management API
# The exam may show this pattern and ask what "keyName: Key2" does
POST https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/{rg}/providers/
Microsoft.CognitiveServices/accounts/{resource-name}/regenerateKey?api-version=2023-05-01
Body:
{
"keyName": "Key2" # Specifies WHICH key to regenerate (Key1 or Key2)
}
# Result: Key2 is regenerated (a new value is created)
# Key1 is NOT affected
# This is the secondary subscription key being reset — not both keys
Choosing the right security approach for any scenario
| Scenario Keyword | Right Answer | Reason |
|---|---|---|
| "No credentials in code" | Managed Identity + DefaultAzureCredential | Managed identity has no credentials to store — Azure handles it automatically |
| "Code runs outside Azure" / "CI/CD pipeline" | Service Principal with client secret | Managed identity only works inside Azure. External code needs a service principal. |
| "Multiple services share the same identity" | User-Assigned Managed Identity | User-assigned identities can be assigned to multiple resources simultaneously |
| "Not accessible from the public internet" | Private endpoint (S0 tier) | Private endpoint removes the resource from public internet entirely |
| "Only accessible from our office IP" | IP Firewall rules / Selected Networks | Firewall rules block all IPs except those explicitly allowed |
| "Store API keys securely" / "No secrets in config files" | Azure Key Vault | Key Vault is purpose-built for secure secret storage |
| "Rotate keys without downtime" | Two-key rotation (Key1 / Key2) | Switch to Key2, regenerate Key1, switch back |
| "Manage your own encryption keys" | Customer-Managed Keys (CMK) via Key Vault | CMK lets you control the encryption keys used on your data |
| "App only needs to call the AI endpoint, not manage it" | Cognitive Services User role | Least privilege — User role grants endpoint access only, no management permissions |
| "Owner / Contributor can't call the AI endpoint" | Add Cognitive Services User role | Owner/Contributor are management roles, not endpoint access roles |
Security questions — what to watch for
1. Owner ≠ endpoint access — Giving someone the Owner role
does NOT let them call the AI service endpoint. They need
Cognitive Services User role for that. This is tested constantly.
2. F0 cannot use private endpoints — Any scenario
requiring network isolation requires S0 tier minimum.
3. Speech needs custom domain before private endpoint —
Unique to Speech service. Other services don't have this requirement.
4. CMK requires soft delete + purge protection ENABLED —
A wrong answer often says "disable soft delete". It must be enabled.
5. System-assigned vs user-assigned managed identity —
Multiple resources sharing one identity → user-assigned.
One resource, one identity, auto-deleted with resource → system-assigned.
6. Key2 regeneration only resets Key2 —
"keyName": "Key2" resets the secondary key only.
Key1 is untouched. The exam asks "what is the result of this request?"
and the answer is always "only the specified key is reset."
Test your understanding
6 questions. Select an answer to see the explanation immediately.
What is the most likely cause and how should it be resolved?
A is correct. This is the most famous RBAC trap in the AI-102 exam. The Owner role grants management permissions (create, delete, configure the resource) but does NOT grant access to call the AI service endpoints. To call the endpoint, the developer needs the Cognitive Services User role assigned. API keys don't expire (option B), the tier doesn't cause 401 errors (option C), and region doesn't cause 401 (option D).