docs
/
Courses — AppEngine

AppEngine Authentication, API keys and organization isolation

Watch on YouTube ↗

Video chapters
  1. AppEngine Authentication
  2. Start with your organization, session and source
  3. Choose the credential for the caller
  4. Find the maintained API key contract
  5. A scope is an authority boundary
  6. Create and install a new scoped key
  7. Run the job and download its CSV
  8. Verify write and administration refusals
  9. Verify the organization header
  10. Read metadata and interpret usage
  11. Regeneration is an immediate cutover
  12. Regenerate and test both secret versions
  13. Pause and reactivate the key
  14. Revoke the training key and confirm refusal
  15. One account can have separate device sessions
  16. Check both client sessions before blocking
  17. Block the laptop and test all three outcomes
  18. Access controls verified by their outcomes

Written guide

Illustrated developer course · Current-source and live-outcome review · Video ready for review

Give a trusted server job its own AppEngine key, prove what that key can and cannot do, replace it safely, and retire its access. Then use a separate customer account to see what happens when one device is blocked while another remains signed in. The companion performs real AppEngine operations; it is a developer example, not Appmint Studio.

Before you start

Open Appmint Studio and sign in to your own development organization. Open the AppEngine API reference for the current routes and request contracts. The Studio website and your assigned API origin have different purposes: configure the API origin supplied for your deployment, not an assumed Studio URL.

If you do not yet have the organization or staff session, API Foundations shows organization setup at 0:50 and the current contract at 1:26. Its staff/customer identity chapter, 7:11, identifies which sign-in route and token to use. Complete any returned code or temporary-password challenge. The sign-in chapter, 2:26, and two-factor chapter, 3:02, show those flows.

Have a legitimate staff account permitted to create and manage its own API keys in this organization. The administrative revoke demonstration uses this organization's ConfigAdmin authority. Do not use cross-organization operator routes. A normal organization does not need to be the platform organization to manage these course keys.

Use harmless training reservations. The filmed job reads existing controlled bookings; it does not alter them. Choose a date window containing your own rows. Prepare a separate customer for the device exercise, with two sessions whose request metadata identifies the intended sample clients. Do not block a device that another person depends on.

The Custom API Gateway course covers browser-to-server sessions at 1:57, two-customer isolation at 4:45, and application plus person identity at 8:48. Those are prerequisites for a gateway serving people; this lesson concentrates on credentials for jobs and account protection.

1. Choose the credential for the actor

A customer token represents a customer. A staff token represents a staff member and their current permissions. An application credential identifies your integration; when a supported route needs the person behind that integration, carry that person's identity as described in the Gateway course. None of these become interchangeable because they belong to the same organization.

A nightly export has no customer clicking a button. Give the trusted job its own API key and only the scope it requires. Keep orgid with every job request: it selects the organization in which AppEngine resolves that credential. Changing an organization header is not a way to grant access elsewhere.

This example keeps staff/customer tokens and job secrets on its local Node server. The browser receives an HttpOnly session cookie and safe metadata. A production deployment also needs HTTPS, Secure cookies, appropriate session persistence/expiry, request protection and a real secret store. Do not put a job key into a publicly distributed browser or phone application.

2. Discover the key contract and understand its scope

In the maintained reference, search api-key, then inspect POST /api-key/create, GET /api-key/{keyId}, regeneration and revoke. The create form needs a useful name, scopes and a deliberate expiry. The returned apiKey is the one-time secret. The record's sk is the management identifier; its prefix helps identify the secret version without exposing the complete secret.

Current scope checks use action:area, such as read:data. The important distinctions are:

RequestRequired scopeMeaning
POST /repository/find/reservationread:dataA read query, even though HTTP uses POST.
PUT /repository/create for an ordinary recordwrite:dataA data write; a read-only key is refused.
GET /repository/collectionsread:adminCollection administration, separately scoped.
Repository operations on users/devicesread:users or write:usersA separate area from ordinary business data.
Profile/security routesread:profile or write:profileRoute and actor checks still apply.
Billing and analytics operationsTheir corresponding areasCheck the exact current route and its additional rules.

read:data is not reservation-only permission. It grants ordinary-data reads in the organization. Your reservation query chooses what this job requests; it does not narrow the key's authority to that collection or to one customer's rows. Give this kind of credential only to a trusted server job. For a customer application, use its customer APIs and caller identity instead.

A recognized write:<area> also includes reads in that area. Wildcard or broad action grants are not needed for this exercise. Unrecognized scope strings grant nothing. The current maintained documentation still contains some older storefront:read examples; the scope used here was checked against the running AppEngine implementation and actual successful/denied requests. Recheck the current contract when adapting the example.

3. Create the key and install it on the job server

Start the companion server using the instructions below. Connect your staff account, open Job credentials, then Create training key. Name it Nightly confirmed-booking export, choose read:data, and set an expiry in the future. Select Create and install on server.

The server calls AppEngine's supported creation endpoint. It receives the secret once, stores that secret in this demonstration server's memory, and returns only the key's safe metadata to the page. Confirm the name, scope, prefix, active status and expiry. Reopening metadata does not recover the full secret.

This is intentionally an in-memory course example: restarting the companion clears the installed job secret. In a real job, write the creation response's secret directly into the secret-management system used by that deployment. Store the management ID separately so you can inspect usage or replace the key later. If you lose the secret, regenerate it; do not expect list/get to reveal it.

The actual new key after creation. Only metadata and a prefix are shown; the full secret remains on the companion server.
The actual new key after creation. Only metadata and a prefix are shown; the full secret remains on the companion server.

4. Run an actual booking export

Choose a UTC start date and an exclusive end date. Run export now executes one real job run. It sends orgid and x-api-key to POST /repository/find/reservation, queries the intended booking status/date window, reads subsequent pages, and converts the returned records to CSV.

Inspect the visible booking row and download the CSV. Match the booking's identity, title, start time and status. A success response with zero rows is an empty result, not proof that a particular booking was included. Check the date window and status before broadening the query.

The default filmed run exports confirmed bookings. The companion's pagination was also verified against two existing new bookings with page size one; it read three API pages, including the terminal empty page, and produced the same record-ID set as a larger single-page query. The job stops according to the actual pagination response, rather than assuming the first page is the whole result.

CSV cell quoting is not sufficient for spreadsheet safety. The implementation also neutralizes formula-leading values before writing user-controlled strings into a CSV. Keep that protection when adapting the export.

A scheduler can invoke the same job with the key supplied through its secret environment. The film runs an execution manually; it does not claim that a timer or external spreadsheet integration has been deployed. Keep the job's business checkpoint and retry policy explicit in your implementation.

The actual confirmed booking returned by the job, with a CSV download generated from those records.
The actual confirmed booking returned by the job, with a CSV download generated from those records.

5. Verify refusals and organization configuration

Use Attempt a write. The example sends a harmless proposed training record with the read-only key. The observed response is 403, with api_key_scope: it requires write:data. No record is created by that denied request.

Use Read collection administration. The same key receives 403 because that request needs read:admin. A key that can read bookings does not thereby gain configuration access.

Use Check wrong organization. The companion sends the same current key with a nonexistent course organization header; the current deployment rejects it with 404. Returning to the configured organization succeeds. This proves that this incorrect configuration is refused; it does not claim a read was attempted against another person's tenant. The existing Gateway identity-isolation chapter covers the separate person-to-record boundary.

Keep the distinction between 401 invalid/expired/inactive credentials, 403 insufficient authority, and an invalid organization's observed response. Handle the server's actual code rather than assuming every authentication-related error is the same. Do not broaden scopes simply to make a refused request disappear.

The read-only key is refused when requesting collection administration. A successful data read does not establish administrative authority.
The read-only key is refused when requesting collection administration. A successful data read does not establish administrative authority.

6. Read metadata and usage accurately

Select Read metadata + usage. Confirm that the secret is not returned. Use the prefix, management ID and name to identify the job; inspect last use and request counts before retiring a key.

Usage counts are not successful-export counts. In the verified implementation, key authentication updates usage before a later scope refusal. The demonstration's refused write and administration checks therefore contribute to the authenticated-request count. Track your own completed-job result separately from this credential activity.

Configured rate-limit values and expiry belong to the key contract. Do not interpret a displayed rate-limit field as proof of every failure/recovery condition; test the limits appropriate to your deployment. The course separately verified that a newly created already-expired key was refused with 401, and retired that test key afterwards.

The actual metadata response omits the secret. Four authenticated attempts include the scope refusals; this is not four successful exports.
The actual metadata response omits the secret. Four authenticated attempts include the scope refusals; this is not four successful exports.

7. Rotate without inventing an overlap period

Prepare how the job receives a replacement secret before regenerating. AppEngine regeneration keeps the management record and issues a new secret; the old secret stops working immediately. There is no automatic overlap window.

Select Regenerate secret on the new course key. The companion installs the replacement on its server and retains the previous value only for the controlled denial test. Choose Previous key — denial check and run the export: the observed result is 401. Select Current server key and run again: the actual booking export succeeds. The record identity stays the same; the prefix identifies the new secret version.

For a production deployment that cannot tolerate an immediate cutover, a separately created replacement key can support a staged migration: provision it, deploy and verify it, then retire the old key. That is a deliberate two-key procedure, not a hidden grace period of regeneration. Do not regenerate credentials still used by another live service merely for a tutorial.

The replacement version is installed and returns the same booking. The preceding recorded check rejected the previous secret.
The replacement version is installed and returns the same booking. The preceding recorded check rejected the previous secret.

8. Pause, reactivate and retire access

Set the training key inactive, then run the job. AppEngine refuses it with 401. Reactivate it and verify that the intended read works again. This is a reversible pause.

Use Revoke training key, confirm the specific key, then test the job again. The demonstrated own-organization administrative revoke requires ConfigAdmin authority and leaves the key marked revoked; the job is refused. This management operation is separate from deleting the key record. Check usage and the owning integration before either permanent retirement or deletion.

Retire all unused rehearsal keys. Do not leave extra secrets active because a recording or test finished.

The same training key is now revoked, and a fresh export attempt is refused with 401.
The same training key is now revoked, and a fresh export attempt is refused with 401.

9. Distinguish sign-in protection from device/session control

A sign-in code protects a new authentication step. Blocking a device controls a recognized device's access. Ordinary sign-out clears the app's local session; it is not a substitute for invalidating a lost device's server-side access. Foundations shows second-factor enrollment and challenges; this chapter demonstrates the latter boundary.

The example has two sample clients for one dedicated customer. They send distinct Chrome/macOS and Firefox/Windows user-agent metadata to AppEngine. These are explicit client emulations for a developer exercise, not a claim that two physical computers were filmed. Device recognition derives from request metadata and is not hardware attestation.

The current default policy is sign_out_now. The business owner can choose the staff-specific finish_session alternative, which lets an existing session expire but does not renew it. Read the current policy before explaining the expected result; do not silently change an organization's policy to fit the recording.

Both actual sample-client sessions returned a profile before the block. The Unknown entry is an earlier setup client, not another physical device claim.
Both actual sample-client sessions returned a profile before the block. The Unknown entry is an earlier setup client, not another physical device claim.

10. Block one device and check all three outcomes

Connect the dedicated customer on the companion's Desktop client and Laptop client. Refresh the AppEngine device list and identify the training laptop. First use each client's saved session to read its own profile; both must work before the negative test means anything.

From the desktop session, select Block training laptop. Read back the device's blocked state. Then make three separate checks:

  1. Use saved laptop session: the observed response is 401 after blocking.
  2. Try a new laptop sign-in: the observed response is 403, so the blocked client cannot simply sign in again.
  3. Read desktop profile: the other client's session still returns 200.

The page displays each actual response. A blocked label alone would not establish those session outcomes.

For this deliberate new-sign-in test, the local companion retains the dedicated training customer's password in server memory. That is a development-only test convenience, not a production password-storage pattern. A production client should obtain credentials through its normal sign-in interaction and should not retain a plaintext password for later retries.

The recorded laptop is blocked and its new sign-in is refused; the desktop profile still works. The saved-session401 is a separate earlier beat in the demonstration.
The recorded laptop is blocked and its new sign-in is refused; the desktop profile still works. The saved-session401 is a separate earlier beat in the demonstration.

Run and adapt the companion

The browser example needs Node 22.12 or newer and no package install. Set the assigned API origin and organization ID on the server, then run browser/server.mjs. Open the loopback address printed by the local server and connect your own permitted staff account. Use only a development environment for these lifecycle and device-block tests.

Read the companion README on GitHub and the browser server source. They include the browser client, actual paginated job, TypeScript/JavaScript/Python callers and cURL/Postman request references. Configuration and real secrets belong outside source control. A future code change must be checked against the maintained AppEngine reference rather than a copied historical payload.

The recording uses controlled existing reservations and new course-only keys/accounts. It leaves rehearsal keys retired and preserves existing production credentials. Optional new-device notifications were suppressed only in the isolated organization's settings during fixture setup, then the prior setting was restored. No SMS, external advertising or payment operation is part of this course.

Continue the developer series

  • API Foundations: sign-in, challenges and refresh.
  • Custom API Gateway: server sessions, actor isolation and application/person identity.
  • Data APIs: schema discovery, precise writes and business-action boundaries.
  • Identity Provider: registered relying clients and SSO; use its current evidence labels for protocol demonstrations.