A keyless call to a Foundry model
Create a project, deploy a small model, and call it from Python with no API key. Then break it four ways, the ways the exam asks about.
Portal setup, one Python script, four break-it exercises.
Pay-per-token on a small model. Delete the resource group afterwards.
Free-trial subscriptions have zero model quota. Upgrading to pay-as-you-go unlocks it and keeps the free credit.
Every step shows the expected result, so you can follow without running it.
Steps
- 1. In the Foundry portal (ai.azure.com), create a project. This creates a Foundry resource with the project inside it.
- 2. Deploy gpt-5-mini with the Global Standard deployment type.
- 3. In the project's Access control (IAM), assign yourself Foundry User. Note the least-privilege choice: not Owner, not Azure AI Developer.
- 4. Copy the project endpoint: https://<resource>.services.ai.azure.com/api/projects/<project>.
- 5. On your machine: pip install "azure-ai-projects>=2.3" azure-identity openai, then az login, then set PROJECT_ENDPOINT and MODEL_DEPLOYMENT.
- 6. Run the script below.
"""Week 1 skeleton: a keyless call to a model in a Foundry project.
Setup (once):
python -m venv .venv && source .venv/bin/activate
pip install "azure-ai-projects>=2.3" azure-identity openai
az login
export PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export MODEL_DEPLOYMENT="gpt-5-mini"
Run:
python main.py
"""
import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
NOTE = (
"Policyholder reports rear-end collision on 6 Oct at a traffic light in Pune. "
"No injuries. Bumper and tail light damaged. Photos uploaded. Third party admitted fault."
)
def main() -> None:
project = AIProjectClient(
endpoint=os.environ["PROJECT_ENDPOINT"],
credential=DefaultAzureCredential(), # keyless: uses your az login or a managed identity
)
client = project.get_openai_client()
response = client.responses.create(
model=os.environ.get("MODEL_DEPLOYMENT", "gpt-5-mini"),
input=f"Summarise this claim note in two lines for a claims handler:\n{NOTE}",
max_output_tokens=300,
)
print(response.output_text)
print(f"\n[tokens] input={response.usage.input_tokens} output={response.usage.output_tokens}")
if __name__ == "__main__":
main()
Expected output (illustrative; wording varies run to run)
Rear-end collision in Pune on 6 Oct; no injuries; bumper and tail light damaged. Third party admitted fault; photos are on file. [tokens] input=74 output=152
Output tokens include the model's reasoning tokens, which are billed as output.
Break it on purpose
Break it 1 · Remove your role
Do: In IAM, remove your Foundry User assignment and run again (role changes can take a few minutes).
You will see: an HTTP 403 permission error for your identity.
Why it matters for the exam: keyless access is only as good as the role behind it; Foundry User is the least privilege for building.
Practice: d1-q1
Break it 2 · Use the old length parameter
Do: Replace max_output_tokens=300 with max_tokens=300.
You will see: an HTTP 400 error: the parameter isn't supported for this model.
Why it matters for the exam: reasoning models reject max_tokens and temperature; the Responses API uses max_output_tokens.
Practice: d1-c1
Break it 3 · Use an API key instead
Do: Create the client with the resource key instead of DefaultAzureCredential, then try to create an agent or run an evaluation.
You will see: model calls may work, but agents and evaluations fail: they require Entra ID.
Why it matters for the exam: keys grant full access with no role scoping, and Foundry's agent and evaluation features don't accept them.
Practice: d1-y2
Break it 4 · Hit the rate limit
Do: Lower the deployment's TPM to the minimum and send 30 requests in parallel.
You will see: some requests return HTTP 429 with a Retry-After value.
Why it matters for the exam: a 429 means wait and back off; then check quota per model and deployment type.
Practice: d1-o1