Beta

Create a tenant

A new tenant starts with its own users, OAuth settings, audit history and logs. You are its first Tenant Admin.

The sample photo API

A real resource server on your tenant's own host, for practicing with tokens, audiences, scopes and authorization.

For the concepts behind this API, learn what a resource server is responsible for.

The sample API is a contained lab resource. It keeps your tenant's sample albums, photos and print orders, accepts only your tenant's access tokens, and runs no code of yours. The BTL organization does not host it.

Turn it on

The Lab Photos preset (Overview, Reset tenant) creates the Photo API resource at https://<tenant host>/lab-api/photos, makes it the default resource, turns the sample API on and adds Ava's and Cora's albums. To do it by hand, register a resource under Resources, then open OAuth Management, Sample API, choose that resource and turn the API on. Tokens must carry the resource's audience: name it with the resource parameter, or make it the default resource.

Operations

The operations, with the scope each needs by default and the authorization engine action it is checked against:

Sample API operations
RequestDefault scopeEngine action
GET /lab-api/photosNoneNone
GET /lab-api/photos/meNoneNone
GET /lab-api/photos/albumsphotos.readalbum.view
POST /lab-api/photos/albumsphotos.writeNone
GET /lab-api/photos/albums/{album}photos.readalbum.view
GET /lab-api/photos/managed/albums/{album}/inventoryphotos.readNone
GET /lab-api/photos/pipeline/albums/{album}/inventoryphotos.readNone
DELETE /lab-api/photos/albums/{album}photos.deletealbum.delete
POST /lab-api/photos/albums/{album}/photosphotos.writealbum.upload
GET /lab-api/photos/albums/{album}/photos/{photo}photos.readphoto.view
DELETE /lab-api/photos/albums/{album}/photos/{photo}photos.deletephoto.delete
GET /lab-api/photos/albums/{album}/sharesphotos.readalbum.view
POST /lab-api/photos/albums/{album}/sharesphotos.sharealbum.share
POST /lab-api/photos/print-ordersprints.createalbum.print
GET /lab-api/photos/print-ordersprints.createNone
GET /lab-api/photos/scim/v2/Usersphotos.accountsNone
POST /lab-api/photos/scim/v2/Usersphotos.accountsNone
GET /lab-api/photos/scim/v2/Users/{account}photos.accountsNone
PUT /lab-api/photos/scim/v2/Users/{account}photos.accountsNone
DELETE /lab-api/photos/scim/v2/Users/{account}photos.accountsNone

Bodies are JSON. Create an album with {"title": "Finals"}, add a photo with {"title": "Podium", "status": "draft"}, share with {"subject": "user:[email protected]", "relation": "viewer"} (add "remove": true to stop sharing), and order prints with {"album_id": 4410, "photo_ids": [9001]}. You can change each operation's scope, and require a sign-in within a number of seconds, with two factors, or meeting one of the tenant's authentication levels.

The pipeline and managed-workload inventory operations are program operations with independently persisted scope choices. They require an active lab case and the case's own authenticated client; managed inventory also requires its current workload registration. User recency, MFA and authentication-level choices do not apply and are refused if submitted. They read only the case's album and photos. Every Sample API call from a hosted lab service, including a token exchanged from one, stays within the case's resources even when an ordinary client scope is broader. Ending the case, changing its trust or registration, or resetting/restoring the tenant ends that authority under either validation method.

Token validation

Local validation checks the JWT's signature with the tenant's published keys, its issuer, expiry and typ, as an API without access to the authorization server does. A revoked token keeps working until it expires, and opaque tokens are refused. Recency, two-factor and level requirements read auth_time, amr and acr from the token, so its access token manager needs Authentication context turned on; a token without them is challenged. Introspection reads the token's current state, so revocation takes effect at once, and it always knows when and how the user signed in. Either way the token's aud must include the resource's audience.

Challenges

Every refusal carries a WWW-Authenticate header. At the API's identifier URL, /lab-api/photos itself, it also carries resource_metadata pointing to the API's protected resource metadata, whose resource is that same URL, as RFC 9728 section 3.3 requires of metadata reached from a challenge. Other paths leave it out; clients find the metadata from the identifier. A request without a token gets a bare challenge (RFC 6750). A bad, expired, revoked or wrongly addressed token gets error="invalid_token". A missing scope gets error="insufficient_scope" with the scope needed. A sign-in that is too old, or without two factors, gets error="insufficient_user_authentication" with max_age (RFC 9470), so the application can send the user to sign in again with that max_age. One that does not meet the operation's level gets the same error with acr_values naming the level to ask for.

Enforcement

After the token and scope, the API asks the authorization engine whether the user may take the operation's action on the album or photo. When the user may not even see that album or photo, the API answers 404, exactly as for one that does not exist, so a refusal never reveals that it exists. When the user can see it but may not take this action, such as deleting a shared album, it answers 403 with the engine's reason. Either way Audit records the engine's reason, such as no_grant. It answers 503 when the engine cannot decide. Creating an album makes its creator the owner, and each new photo names its album as parent. A client credentials token has no user, so it can only read /me, place and list print orders, which its prints.create scope authorizes, and manage the app's own accounts over SCIM at /scim/v2/Users, which its photos.accounts scope authorizes. Those accounts belong to the photo app alone and give nothing in the tenant; the tenant itself can keep them in step with its directory through outbound provisioning. Every answer to a valid token is recorded in protocol Audit as a photos.* operation with its reason, and each decision is explained in the decision log.

Sample data

Replace sample data removes every album, photo and print order and their relationships, then adds Cora's Sports day album (4410) with photos 9001 to 9003 and Ava's Summer trip (4420) with photos 9011 and 9012. Ava and Cora must exist as tenant users. A tenant can keep 2,000 albums, photos and print orders together, shown in its usage view.

We value your privacy

We use cookies and similar technologies to enhance your browsing experience, and analytics to understand our traffic. By clicking "Allow all", you consent to optional analytics. Cookie Policy

Documentation