DL auth

How it works

auth.dliu.com is a small, static page for obtaining a Microsoft-issued API access token. Sign in with an assigned Microsoft account, save or copy the token, then use it in a trusted API tool or agent. Microsoft handles sign-in and token issuance; this site does not run its own authentication broker.

1 token issuerMicrosoft Entra ID, not this website
0 auth backendsStatic files; no token API or session database
Browser-only memoryReusable until cleared, the page closes or Microsoft expiry
Components and trust boundaries
BrowserYou and your tools
Token pageMicrosoft MSAL runs in your browser; the token is briefly visible here.
Trusted API clientReceives the copied bearer token. No Microsoft password or refresh token is copied.
CDNCloudFront
HTTPS and headersDelivers the site with no-store responses and a restrictive Content Security Policy.
Global edge deliveryAll CloudFront edge regions are eligible, including Europe and Asia. Supports HTTP/2 and HTTP/3; clients negotiate the protocol.
Static routingA small edge function maps /docs to the docs file. It does not process tokens.
S3Private static files
Site bucketHTML, CSS, locally bundled MSAL and public application configuration. No user tokens or signing secrets.
Identity / APIMicrosoft and AWS
Microsoft Entra IDSign-in, MFA, application assignments, consent, token issuance and signing.
API GatewayValidates Microsoft's signature, issuer, audience, expiry and route scopes.
Application LambdaChecks trusted gateway context, approved client, the shared assigned-user role and the site's route scope, then performs the operation.

Obtaining a token

Microsoft sign-in to browser-only token use
1. Open authClick Sign in with Microsoft. All integrated site API scopes are requested automatically.
2. Sign in at MicrosoftMicrosoft handles credentials, MFA, account assignment and consent.
3. Return to the browserMSAL exchanges the authorization code with PKCE. The static server never receives the access token.
4. Save or copySave the token and UTC expiry to a local file, or copy the token. It stays on this page so you can repeat either action.

There is no permission picker. The console requests the configured Video, Files, Blog and Trip planner API scopes together. API access requires assignment to the shared dliu API user role; ordinary website sign-in does not grant API access.

One logical API, multiple sites

The existing dliu API Entra registration defines the shared audience and per-site API permissions. It also serves as the browser client with an exact SPA callback at https://auth.dliu.com/redirect.html. No client secret is needed.

A token can work across sites only after each API is configured to trust that same resource and enforce the shared API role and its own scopes. This does not change the sites' ordinary website sign-in or make a token for Microsoft Graph valid for these APIs.

Uses Microsoft's authorization-code flow with PKCE and MSAL Browser. Video's managed API has passed live read/write verification. Files, Blog and Trip planner require their own configuration, release and live API verification before use.

Running costs

The token console is static. There is no always-on server or authentication database. Opening the page delivers files; obtaining tokens happens directly with Microsoft.

ServiceWhat is billedWhen it runs
Amazon S3Small site files and origin requestsStorage and CloudFront origin reads
CloudFrontHTTPS requests and data transferSite and documentation visits
CloudFront FunctionViewer-request invocationsEvery viewer request; rewrites only the fixed documentation path
Route 53 / ACMExisting hosted-zone/DNS billing; certificate terms depend on the certificate typeDomain and HTTPS setup
Microsoft EntraYour applicable subscription and identity feature licensingSign-in, assignments, consent and token policies
Application APIsEach site's API Gateway, Lambda, storage and transfer costsOnly when that API is called; these costs are separate from Auth

These are billing components, not a quoted monthly total or a promise of free usage. The deployment uses no-store responses rather than caching the console, and CDK may create deployment-only helper functions. Application API costs are separate.

CloudFront uses Price Class All rather than limiting eligible edge regions. Charges depend on traffic, delivery region and the account's remaining applicable allowance; enabling global delivery does not guarantee a zero-cost bill.

See CloudFront pricing and S3 pricing for current rates.

Security

Microsoft issues and signs the token. AWS validates it at the API boundary. This page retains it in the current browser page, which must remain trusted while the token is present.

ResponsibilityManaged byBoundary
Password, MFA and sign-inMicrosoftCredentials are entered on Microsoft's sign-in page.
API assignment and consentMicrosoft EntraExplicit assignment to the User-only dliu API user role is required; ordinary website users are not API users.
Token issuance and signingMicrosoftNo site-generated JWT, client secret or custom signing key.
Signature and standard claim validationAWS API Gateway JWT authorizerUses Microsoft's cached public keys; rejects invalid tokens before Lambda invocation.
Application authorizationEach application's LambdaRequires trusted gateway claims, the approved client, the shared API user role and exact site-specific route scope before running the action.
Token display and exportThis page and your deviceA compromised page, extension or device can steal the token while it is available.

Automatic cache-clearing decision

Auth is excluded from the one-day automatic cache-clearing policy. CloudFront uses CACHING_DISABLED, every response has Cache-Control: no-store, max-age=0, and error-cache TTLs are zero. There is no edge-cache retention period to expire, so no scheduled cache-clearing job or one-day cache lifetime is needed. Normal deployments still invalidate /* to publish releases; that is separate from periodic clearing.

The private S3 bucket holds the site's source assets, not an expendable cache or user tokens. Do not apply a one-day S3 object-expiration rule or delete those assets as cache cleanup: the site needs them to remain available. This decision does not change current-page token memory, explicit user exports or Microsoft's token expiry and revocation rules.

No saved token cache

MSAL is configured with memory-only storage and explicit no-cache directives for access, ID and refresh tokens. The SDK cache is cleared immediately after acquisition, including on failure. Only the access token is displayed or exported.

The token stays in the current page's JavaScript memory after saving, copying or switching tabs. Clear, reload, navigation, closing the page or Microsoft expiry removes it from this page. It does not save tokens in cookies, local storage, session storage, IndexedDB, a backend or logs. MSAL may use session storage for temporary OAuth transaction metadata. JavaScript memory is not guaranteed to be forensically erased.

Auth's static hosting never receives the generated token. When a trusted client uses it against an application API, API Gateway and the request handler process it for that request, without an application-level user-token cache or persistent token store. Warm Lambda runtimes can retain physical memory until garbage collection; there is no promise of instant forensic erasure when an invocation returns.

Clearing is not revocation. The clipboard may still contain the token, clipboard history may retain it, and an explicitly saved file persists until you remove it. Exported tokens remain valid until Microsoft's expiry. The page cannot clear copies in your files, tools or agents.

Token lifetime and revocation

An app-specific Entra token lifetime policy has been assigned with a target of 23:59:59, just under 24 hours; it is not an organisation-wide default. Actual issued-token lifetime remains unverified. Without an effective custom policy, access tokens commonly last 60-90 minutes. Always use the actual expiry displayed from Microsoft's response; the page cannot extend an existing token.

A copied access token cannot refresh itself. Microsoft may reject future issuance or renewal, but removing an assignment, signing out or clearing this page does not guarantee immediate invalidation of an already-issued bearer token.

What a site compromise means

With no stored credentials or user tokens and no active user browser running the site, control of the static server alone does not let an attacker forge your Microsoft token. But malicious page code can steal a token on your next visit, and an open page may attempt SSO using an existing Microsoft session even without another password prompt.

HTTPS encrypts the connection. It does not prevent XSS, compromised JavaScript or device compromise. Locally bundled scripts, no third-party analytics, a restrictive CSP, no user-generated HTML, no-store responses and explicit clearing/expiry reduce exposure; they do not make an untrusted page safe.

Threat model: an attacker knows the source code

Assume an attacker can read the entire public repository, the bundled browser code, OAuth application identifiers, redirect URLs and API documentation. None of those is a password or signing secret. Knowing them does not let the attacker forge Microsoft's token signature or grant themselves an API role. Security must come from verified tokens and explicit authorization, not hidden source code or undisclosed endpoints.

Attacker capabilityBoundary and remaining risk
Reads or copies the public codeMicrosoft still controls account authentication, consent and assignment. Each API must validate the signature, tenant, audience, expiry, user identity, role and exact route scope. The static console is not the API authorization boundary.
Knows the public SPA client IDA public client has no secret. The client ID and token's azp are not proof that the caller is the official webpage. PKCE protects the authorization-code exchange; it does not make a public client confidential or protect an already-stolen bearer token.
Steals a copied token or plaintext credential fileThe bearer can exercise every granted permission until expiry or earlier rejection. A shared api.access token with all requested scopes can affect all integrated apps, including destructive operations. Keep exports private and give them only to trusted tools.
Controls deployed page code, dependencies or the deployment accountMalicious code can capture tokens during future visits or acquisitions. No-store, HTTPS and a clean public repository do not stop an authorized publisher from serving malicious code. Protect deployment access and review dependency and release changes.
Controls the browser, an extension or the local deviceThe displayed token, clipboard and saved files may be exposed. Current-page memory is a retention limit, not protection against a compromised device. Clearing the page cannot erase external copies or guarantee immediate revocation.

What threat-model tests can establish

Use synthetic credentials and isolated browser mocks to test configuration rejection, explicit scope requests, disabled SDK token caching, cache cleanup after failed acquisition, export formats, repeat copying, expiry, navigation and stale-operation handling. Infrastructure checks can assert private-origin access, CSP, disabled edge caching and no-store headers. Negative tests are evidence for those tested boundaries, not proof that every attack is impossible or that live Entra and every application's authorization settings are correct.

The known-source review exercised the installed MSAL implementation's PKCE/S256, state and nonce rejection, popup/bridge restrictions and cleanup, origin lookalikes and malformed credential exports with synthetic data. It found no confirmed exploitable issue or real secret in the reviewed publishable source snapshot. This was a local review, not a live penetration test, a dependency-advisory guarantee or clearance of future edits, remote Git history or other applications.

The dependency-advisory check on 2026-11-02 reported a moderate denial-of-service advisory in minimatch, bundled by the installed CDK library. This dependency is used by local deployment tooling, not the browser token console. No attacker-controlled glob input was found in the reviewed Auth deployment path. The audit reported no automatic fix; monitor a compatible CDK update rather than treating the dependency audit as completely clean.

Before publishing source

Review every file selected for commit and the Git history for credentials, bearer tokens, private configuration and personal information. Ignore rules do not remove data already tracked or committed. Keep generated configuration and deployment artifacts out of source control, use placeholders in examples, and review dependency changes. If a real secret has been exposed, removing it from the latest file alone is insufficient: revoke or rotate it and address the published history.

See Microsoft's access-token guidance and configurable token lifetimes.

Shared API authentication

This is the authentication reference for dliu.com APIs: obtaining a Microsoft-issued access token, saving/loading local credentials and sending the token. Each application's API documentation owns its endpoints, payloads, responses and required scopes/roles, and links here for authentication.

  1. Sign in with a Microsoft account that is assigned the required API access.
  2. All integrated site permissions are requested automatically; check the displayed expiry.
  3. Save or copy as needed while the token remains valid.
  4. Use the trusted API URL and route documented by the application, not an assumed website API origin.
  5. When the token expires, return here for a new one. There is no refresh token to export.

One API user role, site-specific scopes

All sites share Microsoft's token issuer, API audience and approved browser client. The User-only dliu API user role, whose token value is api.access, is shared by Video, Files, Blog and Trip planner. Assignment to this role permits API access across all four sites, but each operation still requires its exact delegated scope. The role never bypasses scope checks, token validation or an application's existing data-access rules.

API access does not replace website sign-in, cookies or share links. Other organisation users can continue using the standard webpages without this role; a website session never substitutes for the API role. Assign the role only to the intended API operator, not to every organisation member.

ApplicationRequested delegated scopes
Videovideo.read, video.write, video.delete
Filesfiles.read, files.write, files.delete
Blogblog.read, blog.write, blog.delete
Trip plannertrip.read, trip.write, trip.delete

The application's API guide defines which scope each operation requires and any additional access restrictions. The shared API role is an application permission, not a Microsoft directory-administrator role. The token console never requests Microsoft Graph management permissions.

After an administrator adds an integration, scope or role assignment, obtain a new token here and save it again. An already-exported token does not acquire new claims, and clients cannot renew it by editing ~/.dliu_token. Only configured and deployed APIs are usable; the application guide gives its actual managed API URL.

Saving a local token file

After sign-in, choose Save file. In supported desktop Edge and Chrome, the native Save As dialog suggests .dliu_token; choose your home folder to save it at ~/.dliu_token. A website cannot silently select or write to your home directory. It does not upload the token or retain a file handle.

Chrome on macOS sanitizes suggested filenames and can remove the leading dot. The site still requests .dliu_token, but cannot override the browser's filename sanitization. Type the leading dot back into Save As before saving. If a different name is chosen, the page warns that clients need the default name; a file named dliu_token is not ~/.dliu_token.

Browsers without a Save As API show Download file instead. Move the downloaded file to your home folder and ensure its name is .dliu_token, including the leading dot.

token=<Microsoft-access-token>
expires_at=<actual-expiry-in-UTC>

Copy token file copies this complete two-field record, including the actual UTC expiration time, for you to paste into ~/.dliu_token as plain text. Copy token copies only the access token for a trusted tool's bearer-token field; it is not a complete credential file. Neither copy action writes a local file or discards the valid token from this page.

The expiry comes from Microsoft's response, not a fixed 24-hour assumption. The file contains no ID token, refresh token or password. Saving, copying, cancellation or failure leaves the valid token available for another attempt. Clear, expiry or leaving the page cancels a save still waiting for a destination. An operation already committing to disk may finish; clearing the page cannot undo a saved file.

The file is plaintext. Keep it private and outside source control. The browser controls filesystem permissions; on macOS/Linux you can restrict access with chmod 600 ~/.dliu_token. Clearing the page does not delete the saved file or revoke its token.

Default credentials for clients and agents

Look for ~/.dliu_token on the machine running the API client or agent. Parse the two fields as data; do not source the file or print its contents. Reject missing, malformed or expired credentials before sending a request. A remote agent cannot automatically read a file on your Mac: provide credentials through its approved secret configuration, never through chat or the Auth website.

Application requesters reread this file for every request. An explicit access-token override takes precedence; an empty/invalid override fails instead of falling back. A token-file override selects an absolute credential-file path (use $HOME/.dliu_token, not a literal ~/ in that variable). Saved-file mode checks both expires_at and JWT exp, using the earlier expiry. Raw-token-only files need a fresh Save file export. These local checks are not signature authorization; the application gateway still validates Microsoft's token.

RequesterAccess-token overrideToken-file override
VideoVIDEO_API_ACCESS_TOKENVIDEO_API_TOKEN_FILE
FilesFILES_API_ACCESS_TOKENFILES_API_TOKEN_FILE
BlogBLOG_API_ACCESS_TOKENBLOG_API_TOKEN_FILE
Trip plannerTRIP_API_ACCESS_TOKENUses the default file; its API guide documents supported overrides.

Overrides are optional; the default workflow uses the saved file. These variables configure the local requester, not Auth. Application guides supply each requester's API base and site-specific usage. Explicit access-token mode leaves expiry enforcement to the gateway; the requester must not silently fall back to another credential source.

The Video requester alone retains a separate native-client mode selected by explicit native tenant/client/audience settings. Leave those settings unset when using browser-saved credentials; that native client is not approved by the current browser-client API guard. The Files, Blog and Trip planner requesters do not acquire Microsoft credentials themselves.

Sending the token

Use a trusted client's secret bearer-token field, or send this header directly to the application's HTTPS API. Use an access token, not an ID token, password or refresh token. Do not put it in a URL, source control, chat, request logs or verbose HTTP traces.

GET /<application-route> HTTP/1.1
Host: <managed-api-host>
Authorization: Bearer <access-token>

Read-only curl request from the default file

Set API_REQUEST_URL to a trusted HTTPS endpoint from the application's API docs. This example validates the saved record and keeps the token out of curl's command arguments and output; only the API response is printed.

API_REQUEST_URL='https://<trusted-api-host>/<read-only-route>'
python3 - "$API_REQUEST_URL" <<'PY'
import base64, datetime, json, re, subprocess, sys
from pathlib import Path
from urllib.parse import urlsplit

def fail(message):
    raise SystemExit(message)

try:
    lines = (Path.home() / ".dliu_token").read_text(encoding="utf-8").splitlines()
except OSError:
    fail("Cannot read ~/.dliu_token. Use Save file in Auth.")
fields = {}
for line in lines:
    if not line:
        continue
    key, separator, value = line.partition("=")
    if not separator or key not in ("token", "expires_at") or key in fields:
        fail("Malformed credential file. Export it again from Auth.")
    fields[key] = value
if set(fields) != {"token", "expires_at"}:
    fail("The file must contain token= and expires_at= fields.")
token = fields["token"]
if not re.fullmatch(r"[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+", token):
    fail("Invalid access-token format.")
try:
    part = token.split(".")[1]
    payload = json.loads(base64.urlsafe_b64decode(part + "=" * (-len(part) % 4)))
    token_expiry = payload["exp"]
    if isinstance(token_expiry, bool) or not isinstance(token_expiry, int) or token_expiry <= 0:
        raise ValueError()
    saved = fields["expires_at"]
    if not re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z", saved):
        raise ValueError()
    saved_expiry = datetime.datetime.fromisoformat(saved.replace("Z", "+00:00")).timestamp()
except (ValueError, KeyError, TypeError):
    fail("Invalid token or expiry metadata. Export the file again.")
now = datetime.datetime.now(datetime.timezone.utc).timestamp()
if now >= min(saved_expiry, token_expiry):
    fail("Token expired. Sign in to Auth and save a new file.")
url = urlsplit(sys.argv[1])
if url.scheme != "https" or not url.hostname or url.username or url.password or url.fragment:
    fail("Use a trusted HTTPS API URL without URL credentials.")
config = 'header = "Authorization: Bearer ' + token + '"\n'
subprocess.run(["curl", "--fail-with-body", "--silent", "--show-error",
                "--config", "-", sys.argv[1]], input=config, text=True, check=True)
PY

Application API references

Use the application's reference for its managed API URL, endpoints, required permissions, request and response schemas, workflows and errors. Each reference requires this shared authentication guide rather than duplicating credential instructions.

Common failures

FailureWhat to check
Microsoft sign-in is unavailableSite configuration, exact SPA redirect, popup blocking and administrator consent.
Account not assignedEntra enterprise application assignment and the required user role.
401 or 403 from the managed APICorrect endpoint, expiry, Microsoft issuer/audience, approved client, required scopes and role. Do not use an ID token.
Token no longer visibleIt expired, was cleared, or the page was reloaded/closed. Obtain another token; reload does not restore one.