Skip to main content

Labs and answer keys

Six tabletop exercises​

The lessons so far have asked the same two questions at every arrow: what crosses this boundary, and what authorizes the receiver to act? These exercises check whether you can answer them without the lesson text in front of you. Each one takes a situation the course has already explained and changes one condition, so the work is in noticing which condition decides the outcome.

Use fictional identities and inputs throughout. None of the six exercises needs a production account or a cloud API credential; a whiteboard and the running example are enough.

Lab 1: Trace two requests​

Draw the harness, Keycloak, CIE/CAS, AI Gateway, the model and mcp server 1. Then trace Alex's question: "Multiply 12 by 7 and return the MCP server's UTC time."

Deliverable: two labeled request paths and the execution location of each tool.

Answer key: there are two paths, and both end at the gateway before going anywhere else. Inference goes from the harness through the gateway to the model. MCP goes from the native client through the gateway to mcp server 1. The server computes the product and reads its own clock, so the execution location for both tools is the server, not the workstation and not the model. Results return through the gateway. The deciding detail is who holds which credential: the gateway holds the upstream OAuth credentials, and the harness never sees them.

Lab 2: Evaluate the utility grant​

Assume a correctly signed, current token for the configured issuer and MCP audience unless a row says otherwise. For each case, decide what mcp server 1 does with the request.

CaseConditionsAction
AAllowed gateway client, invoke, utilities.use scope and role, matching subject policycalculate
BSame grants as A, but an inference audiencecalculate
CSame as A, but utilities.use is missing from the tokenhash_text
DSame as A, but the utilities.use role belongs to another resource clientformat_json
ESame as A, but no subject bindingcurrent_time
FSame as A, but the client is not allowedgenerate_uuid
GAll grants from A, arguments request division by zerocalculate

Deliverable: distinguish authentication denial, authorization denial, successful execution and input failure.

Answer key: the server checks these conditions in order, and the first failing check names the category. A passes every check and executes. B and F fail token or client validation before any grant is considered: B was issued for the wrong audience, and F arrived from a client the server does not allow. C, D and E fail authorization, because effective access is the intersection of the issued scope, the resource-specific role and the subject binding, and each row removes a different one of those three. G passes every identity and authorization check and then fails on its arguments, so it returns an input error. That is why login is not a repair for G: nothing about the credential was wrong.

Lab 3: Separate directory lookup from login​

CIE has alex@example.com. CAS accepts a SAML assertion whose configured username field contains alex. The gateway cannot resolve a provisioned user. Another realm also contains the email alex@example.com.

Deliverable: name the mapping to inspect and explain why matching emails do not establish one identity.

Answer key: the login succeeded and the directory record exists, so the failure is in the join between them. Compare the SAML attribute the gateway actually consumes (including NameID if that is the configured field) with the field the provisioned record is looked up by; here one side carries alex and the other carries alex@example.com. The second realm is the reason an email match cannot be the fix: an email is a lookup attribute, and two issuers can hold the same email for unrelated subjects, so the durable identity stays issuer plus subject. After the user resolves, verify gateway workspace membership separately, because resolving an identity and being a member of the intended workspace are different facts.

Lab 4: Interrupt rotating refresh​

Two native processes share a credential binding. Process A retires refresh generation 4, receives generation 5, and crashes before saving it.

Deliverable: show the lock, the pending state and the next user's recovery path.

Answer key: only one process exchanges a generation at a time, which is what the binding lock is for. Process A recorded its refresh intent before the exchange, so when the next process acquires the lock it finds unresolved state rather than a clean generation 4. It must request sign-in instead of replaying generation 4, because that refresh token may already have been consumed by the exchange that produced generation 5. The deciding fact is that rotation may already have consumed generation 4, so an uncertain exchange cannot be retried safely. In the normal case, generation 5 is saved before it is ever used, and the second process simply reloads it.

Lab 5: State what utility output proves​

calculate returns 84 and current_time returns a timestamp. The model says it has inspected the gateway's security profile and verified scanning.

Deliverable: replace that answer with two defensible sentences.

Answer key: "mcp server 1 returned 84 for 12 × 7. Its clock reported the displayed UTC timestamp." Each sentence claims only what a completed tool result establishes. Neither utility inspected a security profile or returned a scanner verdict, so the model's original statement asserts evidence that no tool in this inventory can produce.

Lab 6: Reason about idle return and revocation​

A gateway MCP access token remains valid for another 30 minutes, but the upstream user grant has exceeded its idle limit. Separately, an operator removes the user's binding from mcp server 1.

Deliverable: explain why a valid gateway credential may still be insufficient.

Answer key: the gateway credential only gets the request as far as the gateway. To proxy the call, the gateway also needs a usable upstream grant for this user, and that grant expired on its own clock; renewing it may require consent again. The binding removal is a third clock: once every server replica has loaded the new policy, that subject is denied even if it presents an unexpired upstream JWT, because the binding is one of the server's own authorization checks rather than a claim inside the token. CIE workspace deprovisioning would propagate along yet another path. The reason one valid token is not enough is that each receiver enforces its own contract, and those contracts expire and revoke independently.

Optional isolated integration exercise​

The tabletop labs test the model. This exercise tests it against a real gateway route, and it only makes sense in an isolated environment: use a maintainer-provided gateway route, test identity, workspace mapping and utility-server binding. The exercise needs no management-API service account, because the utility tools do not call one. Native credentials still require the appropriate OS store, since that is where the harness keeps them.

StepObservation to record
Request gateway MCP without a credentialOAuth challenge from the intended gateway
Complete gateway and required upstream loginNative save succeeds; correct identity and integration selected
Discover toolsExactly the expected eight utility names
Call each tool with synthetic valid inputCompleted result with the expected type and content
Submit invalid arithmetic, JSON and encoding inputsBounded tool errors without losing authorization
Test missing scope, role or binding in the isolated fixtureDenial at the intended boundary
Continue real activity across token expiryActual utility success with renewed credentials
Return after the preserved idle timeoutClear sign-in guidance and verified restoration behavior
Finish and remove the fixtureLocal credentials and test grants removed without disrupting another test

Two operational cautions follow from the lifecycle lesson. Use dedicated fixture bindings and coordinate issuer logout when tests share a browser SSO session, because inference logout can revoke the client session that another login is relying on. And do not turn a quiet terminal into a keepalive test: idle expiry is an intended policy outcome, so the test should observe it rather than prevent it.

Score the explanation on request routing, execution location, credential separation, the complete utility grant and the limits of the evidence. Keep the last of those honest: a successful utility call shows that the path worked once, and it does not by itself prove timed renewal.

Review Architecture, Utility authorization and Credential lifecycle.