Devices
This service keeps a device register: every phone, computer and host a
trust realm knows, each an entry under ou=devices in the realm’s directory
(LDAP schema), owned by one person or one
application. A device is recognised again by the keys it holds, and each device
records whether it is attested, whether it is compliant, and which
applications used it.
The register was built in six phases (issues #164 and #218): the register;
recognition; compliance and the MDM feed; Shared Signals; risk scoring; and
the issuance policy, an acr and a token claim. All six are built, and a
received CAEP device-compliance-change is acted on by the Shared Signals
receiver (#153). The console’s Protocols → Device registration page
says the same from the running build, and is the one to trust.
Features
- Two kinds of owner. A person (a username), or an application entry — a workload or a server host registering the machines it runs on.
- Keys a device is known by, each with a SHA-256 thumbprint:
x509— a certificate; the thumbprint is over its SubjectPublicKeyInfo, so a renewed certificate over the same key is the same key;jwk— a public JWK or DPoP key; the thumbprint is RFC 7638, which is DPoP’sjkt;webauthn— a security key the owner enrolled, linked to the device;- and the OpenID Connect Native SSO
device_secret, which is not a key and is held only as a hash.
One key belongs to one device in the realm. Keys are public material: a JWK with a private member, or any symmetric key, is refused.
- Attestation: a device is
attestedwhen a verifier checked an attestation statement for one of its keys and it chained to a trusted root, andself-assertedotherwise. The statements verified are an Android Key Attestation, an Apple App Attest statement, a TPM key attestation in a certificate request, and a WebAuthn attestation (checked when the credential was registered). - Compliance:
compliant,not-compliantorunknown(where every device starts), with the previous value and who set it — an administrator, an MDM or posture feed, or development’s test control (below). - Status and risk: a device can be marked compromised, which ends the
sessions it authenticated and revokes what it was trusted with
(below); and it carries a risk level —
LOW,MEDIUMorHIGH— set by risk scoring and by a compromise. - Shared Signals: every change that matters to a relying party goes out as a CAEP or RISC event (below).
- Risk scoring: the device that proved a sign-in is scored — compromised, not compliant, missing, or the person’s own and compliant, which lowers the score (below).
- The issuance policy: facts about the device go into every issuance decision; a compromised device is refused by default, and a realm can require a compliant device (below).
- An acr and a claim:
urn:sts:acr:compliant-device, anddevice_idin the ID Token and the access token (below).
How a device is registered
| Method | Built | What happens |
|---|---|---|
| Native SSO | yes | The first app’s authorization-code grant with device_sso makes the device (OAuth 2.0 and OpenID Connect). |
| An administrator | yes | Directory → Devices (/admin/devices) or POST /admin-api/devices/create, owned by a person or an application, with keys typed by value. A key added this way is recorded as proven by nobody and self-asserted. |
| The owner, on the portal | yes | /portal/devices: proving a key (below), or linking a WebAuthn platform credential enrolled on /portal/keys with a fresh assertion. |
| EST and SCEP | yes | A certificate from the device profile, issued to the device entry. |
| A remembered browser | yes (#265) | “Remember this browser” at sign-in or on /portal/devices: a device known by a signed and encrypted cookie, in any browser. The lowest assurance the register has — below. |
A person sees their devices on /portal/devices and can remove one.
Proving a key on the portal
- The signed-in person asks for a challenge — the Get a challenge
button, or
POST /portal/devices/challengewith{"purpose":"key"}asapplication/jsonfor a device app holding the portal session. The answer names the challenge, theaudto sign for (this page’s absolute address) and thetyp. A challenge is bound to that session, livesdevices.challengeTtlSecondsand is answered once. - The device answers with one of:
- a compact JWS with header
{"typ":"device-key-proof+jwt","alg":…, "jwk":<the public key>}over{"nonce":<challenge>,"aud":<aud>, "iat":<now>}, signed by the key it will be known by (any asymmetric JWS algorithm, ML-DSA included). An Android app adds the key’s attestation certificate chain asx5c; itsattestationChallengemust be the challenge. - an Apple App Attest key id and attestation object, made with the
challenge’s SHA-256 as the client data hash, for an app named in
devices.appleAppAttestAppIds.
- a compact JWS with header
- The person pastes it into the form — or the app posts
{"challenge", "proof" | "app_attest":{"key_id","attestation"}, "device_id"?, "label"?, "platform"?, "model"?, "os"?}toPOST /portal/devices/proof, answered201with the device.
A certificate over EST or SCEP
/.well-known/est/device/simpleenroll (EST, authenticated as usual), or a
SCEP challenge password created for the device profile. The certificate
names only urn:sts:device:<id>: a request whose subjectAltName names an
existing device’s URN certifies a key for that device (its owner, or an
administrator); one naming none creates a device owned by the requester. A
request may carry a TPM key attestation in the id-aa-attestation attribute
of draft-ietf-lamps-csr-attestation, as a TCG tcg-attest-tpm-certify
statement with the Attestation Key’s certificate chain; it is attested when
that chain ends at devices.tpmTrustAnchors. A device renews by enrolling
again, naming its URN; /simplereenroll and SCEP RenewalReq are refused for
it, and ACME does not issue it.
How a device is recognised
Presenting any key a device holds identifies it:
| Evidence | Where |
|---|---|
| a client certificate whose key is a device’s x509 key | a sign-in, and the token endpoint (RFC 8705) — a certificate refused on revocation is not |
| a linked WebAuthn credential | a sign-in |
a DPoP proof whose key (jkt) is a device’s jwk key |
the token endpoint |
the Native SSO device_secret |
the token endpoint |
a remembered browser’s cookie (browser-cookie) |
a sign-in — the weakest evidence, used only when nothing else names a device |
The recognised device is recorded on the sign-in’s authentication event and
on the token issuance. Risk scoring, the issuance policy, the acr and the
device_id claim all read it from there. A compromised device is still
recognised. Monitoring → Devices counts recognitions by kind.
A device found at a sign-in is read again from the register whenever it is used later: at the next token request on that session, and for the acr. So a device an MDM reports not compliant, or an administrator marks compromised, counts as such for everything issued afterwards on sessions it already proved. A device removed since counts as no device.
Remembered browsers
The register above recognises a device by a key it proved: a WebAuthn platform credential, a DPoP key, a client certificate or a Native SSO secret. A general browser often can prove none of these. Linux Firefox, for example, has no built-in authenticator at all. A remembered browser works in every browser, and it is deliberately weaker: the browser carries a token in a cookie rather than proving a key. Whoever holds a copy of the cookie is that browser until the copy is caught. Everything about how the rest of the service treats it follows from that.
How a browser is remembered
- The person ticks Remember this browser on the sign-in screen, or
presses the button on
/portal/deviceswhile signed in. Nothing is remembered unless they ask. - When the session starts, a device is registered for them:
- enrolment method
browser; - named after the browser, for example
Firefox on Linux; - attestation level
bearer, which is belowself-asserted; - no keys.
- enrolment method
- The browser is sent a cookie holding the device token:
HttpOnly,SameSite=LaxandPath=/;Securewith a__Host-prefix when the service is on HTTPS;- one cookie per trust realm.
It lasts
devices.browserTokenLifetimeDays(180 days), and each time the browser is used the clock starts again. Page scripts cannot read it.
What the token is
A nested JWT that only this service ever reads:
- Signed (JWS, ES256,
typ: browser-device+jwt) with a key pair used for nothing else:- in the
per-algorithmsigner model, the realm’s dedicated browser-device signing key; - in
hybrid-groups, the ES256 key of thebrowser-devicessigner group, whose certificate is hybrid with an ML-DSA-44 partner like every group’s.
- in the
- Encrypted (JWE, ECDH-ES+A256KW with A256GCM) to the realm’s own browser-device encryption key. Encryption keeps the device id and the owner out of anybody’s cookie jar. The signature is what makes the token trusted.
- Claims:
issandaud:urn:sts:browser-device:<realm>;sub: the device id;owner: the username;gen: the generation, which goes up by one at every sign-in;jti,iatandexp.
- Classical keys, deliberately. A cookie holds about 4 KB, and a
post-quantum signature does not fit in one. A token that would be too large
is not issued (
STS-DEVICE-0043). The usual cause is settingdevices.browserTokenCertificateHeadertox5c.
Both key pairs are members of the realm’s key set. They are sealed at rest in product mode, shared by every request worker and node, and added to a key set that was stored before they existed. Neither is published.
How it is recognised, and how a copy is caught
At a sign-in, the cookie is decrypted, its signature and claims are checked, and the device it names is looked up. Recognition makes the browser the person’s own recognised device. Beyond that, what the token tells the rest of the service depends on the generation:
| Case | What happens |
|---|---|
| Current generation | The token is issued again with gen + 1 after the sign-in, so the cookie rotates on every use. |
One behind, within devices.browserReissueGraceSeconds (60) |
Accepted as a second tab that signed in at the same moment. |
| Older than that | The cookie was copied. The device is marked compromised, which ends every session it holds, and the cookie is cleared (STS-DEVICE-0041). |
| Names somebody else’s device | Not treated as this person’s device (STS-DEVICE-0042). |
| Presented by a different browser family or OS than it was bound to | Recorded as a changed context. |
| Unreadable or expired | Cleared, and the browser is treated as unrecognised (STS-DEVICE-0040). |
What it counts for
A remembered browser can only remove suspicion. It never adds trust:
- Risk scoring: a sign-in from the person’s own remembered browser is
neither
new-devicenorunregistered-device. It never earns the compliant-device signals that lower risk.- A copied cookie is
browser-token-replayed. - Someone else’s cookie is
browser-token-foreign. - A changed browser is
browser-context-changed.
- A copied cookie is
- Compliance: a
bearerdevice cannot be marked compliant, by an administrator or by an MDM feed (STS-DEVICE-0039). So it never satisfiesdevices.requireCompliantDeviceand never meetsurn:sts:acr:compliant-device. - The issuance policy sees
via: browser-cookieand attestationbearerlike any other device fact, so a rule can tell it apart. - If the person later links a real key to it, the device takes that key’s level.
Skipping the second factor
An administrator may let a remembered browser stand in for the second factor. This is in the realm’s authentication policy on Directory → Policies:
- A remembered browser may skip the second factor: off by default.
- How long a remembered browser skips the second factor: 30 days by default, from the last time the second factor was given on that browser.
Even with the policy on, the second factor is still asked for when any of these is true:
- the sign-in is for the admin console, the user portal or the protocol debugger;
- the person holds a console role (Admin Read or Admin Write);
- the sign-in’s risk is MEDIUM or higher;
- the cookie was copied, belongs to someone else, is presented by a different browser, or names a compromised device;
- a relying party demanded a second factor (
acr_values,wauth), a security key was demanded, or risk scoring asked for a step-up.
When it is skipped, the session is one factor: amr ["pwd"] and acr 1,
exactly as for a person who has no second factor. A relying party that needs
two factors asks for them and always gets them.
The warning: anyone who copies the cookie skips the second factor too, until the copy is caught. The copy is caught the next time either browser signs in after the other, and that ends every session the device holds. Only turn the skip on where that trade is acceptable.
Compliance
A device’s compliance is set through four doors. Each change records the previous value, when, the source and who acted; Monitoring → Devices counts changes by source, day by day.
| Door | Source | Who may use it |
|---|---|---|
An administrator: the Compliance form on a device’s page, or POST /admin-api/devices/set-compliance |
admin |
Admin Write. May also set unknown, withdrawing a vouch. |
An MDM or posture feed: POST /admin-api/device-compliance |
mdm |
A client holding an access token with the device:compliance scope, and nothing else, whose application is a member of the DEVICE_COMPLIANCE role. |
The test control: POST /devices/test/compliance |
test-control |
Anybody, in development only; product answers 403. |
A received CAEP device-compliance-change from a trusted transmitter |
caep |
A federation partner whose Shared Signals this realm receives, as the signal-response policy permits (#153, #373). A device manager is an ssf relationship on Federation (#374). The device is named by its id (an iss_sub subject’s sub) or a key thumbprint. |
Integrating an MDM or posture feed
- Register the feed as an application in the realm
(
/admin/applications/new, orPOST /admin-api/applications/add) with a client secret (or a certificate or key forprivate_key_jwt), and declaredevice:compliancein its allowed scopes (oauthAllowedScope).device:complianceis a protected scope: the token endpoint issues it only to a client that declares it, in both modes, and/admin-apiasks again on every call, so removing it from the application stops the tokens the feed already holds. - Add the application to the
DEVICE_COMPLIANCErole (#309), on/admin/rolesor withPOST /admin-api/roles/add-member{"role": "DEVICE_COMPLIANCE", "kind": "application", "member": "<feed>"}. The role authorizesdevice:compliance. It exists in every realm with no members, so no client is the feed until you add one; declaring the scope alone is not enough. Taking the application out of the role stops the tokens it already holds at the next call. - Get a token with the client credentials grant:
POST /oauth2/tokenwithgrant_type=client_credentials,scope=device:complianceandresource=<base>/admin-api(the resource indicator puts the management API in the token’saud; without it every call is refused401). -
Report:
POST /admin-api/device-compliancewithAuthorization: Bearer <token>and a JSON body — one report, or up todevices.complianceFeedMaxReportsof them:{ "reports": [ { "thumbprint": "fZXwv9eBhY5TwEjZxaWhjv9ad9QunF5Jw0YCDskz_10", "keyKind": "x509", "status": "compliant" }, { "certificate": "-----BEGIN CERTIFICATE-----\n...", "status": "not-compliant", "reason": "Disk not encrypted" }, { "id": "527e640b-72d3-4a7b-89e4-6534c639701e", "status": "compliant" } ] }A report names its device by
id, by a keythumbprint(base64url SHA-256: of the SubjectPublicKeyInfo for a certificate, RFC 7638 for a JWK;keyKindnarrows it) or by itscertificate(PEM) — so an MDM that issued or inventoried a device’s certificate can report it without knowing this service’s id.statusiscompliantornot-compliant;reasonis optional and becomes the event’sreason_admin.
The answer is 200 with applied, refused and results — one per report,
in order, with its id, previous, status, changed and signalled, or
its errors. A report naming no device is refused on its own and the rest
apply; a request with no report or too many is refused whole (400,
STS-DEVICE-0034). The feed sets compliance only: ownership, keys and
status are an administrator’s. A token carrying admin:write is refused here,
so a report recorded with source mdm always came from a feed.
A compromised or removed device
Marking a device compromised (the Mark compromised button on its page,
or POST /admin-api/devices/set-status with "status":"compromised"):
- ends every sign-on session one of its keys authenticated — each a CAEP
session-revokedand its relying parties’ back-channel Logout Tokens; - revokes its Native SSO
device_secret; - revokes every certificate this service’s EST or SCEP Issuing CA issued it, with reason keyCompromise, so its CRL and OCSP responder say so;
- ends every GNAP grant whose client key is one of the device’s keys —
including a client proving by mutual TLS with one of the device’s
certificates — and revokes every OAuth access or refresh token bound to the
device: DPoP-bound to one of its JWK keys, or bound by mutual TLS (RFC 8705
x5t#S256) to a certificate over one of its keys — the certificate the device’sx509key holds, or any other certificate over the same key (one another CA issued, or a re-issue this register never saw), because the key under a bound certificate is recorded when the token is issued (#432). A WebAuthn key binds no token; - raises its risk level to
HIGH; - sends RISC
credential-compromiseandsessions-revokedfor a person’s device (below).
The device stays in the register, recognised and marked compromised. Restoring it puts back the risk level the compromise raised; nothing revoked comes back — a certificate is re-issued, and a secret is minted at the next Native SSO sign-in.
Removing a device ends the sessions it authenticated and revokes its
certificates with reason cessationOfOperation (keyCompromise when it was
compromised), and sends RISC sessions-revoked for a person’s device.
What goes out over Shared Signals
Each event is sent to every stream that asked for its type and covers its
subject, when caep.autoEmitTypes or risc.autoEmitTypes names it (all of
them do by default).
| Event | When |
|---|---|
CAEP device-compliance-change |
a device’s compliance changes in a way a receiver can be told (below) |
CAEP risk-level-change, principal DEVICE |
a device’s risk level changes — risk scoring, or a compromise (HIGH) |
CAEP credential-change |
a device key is added (create), re-issued over EST (update) or removed (delete); a Native SSO secret is issued (create) or revoked (revoke); a device is removed (delete, per credential) |
CAEP session-established, session-presented, session-revoked |
as for every session — and the subject names the device when a registered device authenticated the session |
RISC credential-compromise |
a person’s device is marked compromised: one per kind of credential it held |
RISC sessions-revoked |
a person’s device is marked compromised or removed |
The subject is SSF’s complex subject with a device member —
{"format":"iss_sub","iss":<this realm's issuer>,"sub":<the device id>}, the
form CAEP’s own example uses — and a user member naming the owner when the
owner is a person. A receiver that adds {"format":"complex","device":{…}}
to its stream is sent that device’s events (SSF 1.0 section 8.1.3.1); one that
added the person is sent them too.
Compliance on the wire. CAEP knows two values, compliant and
not-compliant, so a device’s unknown is sent as not-compliant: nobody
has vouched for it. An event goes out only when the sent value changes —
unknown → not-compliant is no event, unknown → compliant is
not-compliant → compliant, and an administrator setting a compliant
device back to unknown is compliant → not-compliant.
initiating_entity is admin for an administrator and system for the feed
and the test control.
Credential types. A certificate is x509 with its issuer and serial; a
linked WebAuthn credential is fido2-platform or fido2-roaming. A device’s
JWK key and its Native SSO secret fit none of CAEP’s registered types, so they
are sent as urn:iya:sts:credential-type:device-key and
urn:iya:sts:credential-type:device-secret — CAEP allows a type the
transmitter and receiver agree on.
RISC and the deprecated sessions-revoked. RISC 1.0 says new
implementations should use CAEP’s session-revoked, and each ended session
does send one. sessions-revoked is sent as well, with the device beside the
person in the subject, meaning every session of this account on this
device. Remove it from risc.autoEmitTypes to send only the CAEP events.
Risk scoring
Every sign-in is scored (Risk scoring). The device that
proved the sign-in adds up to eight signals. Each is a factor on the score, and
risk.signalFactors can change it:
| Signal | Factor | When |
|---|---|---|
compromised-device |
×50 | The device is marked compromised. This is HIGH on its own. |
non-compliant-device |
×3 | The device is not-compliant. |
unregistered-device |
×2 | No device of the person’s own was recognised: none at all, or someone else’s. |
compliant-attested-device |
×0.5 | The person’s own device, compliant and attested. This lowers the score. |
compliant-device |
×0.8 | The person’s own device, compliant and self-asserted. This lowers it less. |
browser-token-replayed |
×50 | A remembered browser presented an older token than its device holds: the cookie was copied, and the device is now compromised. This is HIGH on its own. |
browser-token-foreign |
×2 | The browser carries another person’s remembered-browser cookie. |
browser-context-changed |
×2 | A remembered browser’s cookie arrived from a different browser or operating system than it was bound to. |
unregistered-deviceis scoped. It fires only for a person who has registered a device, or for anybody whiledevices.expectRegisteredis on. It also waits until the person hasrisk.minimumHistoryearlier sign-ins. In a realm where nobody has registered anything, it never fires.- The two lowering factors never make a sign-in scored on their own. They are never applied to a compromised device.
- The person’s own registered device is never
new-device. The history records it under its register id rather than the browser fingerprint. - The device’s own risk level. After a sign-in the person’s own device
proved, the device takes that sign-in’s level:
LOW,MEDIUMorHIGH. CAEPrisk-level-change(principalDEVICE) is sent only when the level changes.- An UNSCORED sign-in sets nothing.
- A compromised device stays
HIGHuntil it is restored.
- Monitoring → Risk shows the device beside the browser on each assessment.
Where the screen’s own WebAuthn step is not scored. The sign-in screen scores the sign-in before its WebAuthn ceremony, because the score decides whether to ask for one. A platform credential presented in that step is therefore not in that sign-in’s score. It is still on the session, so the policy, the acr and the claim below all see it. A client certificate on the connection is scored at every door.
The issuance policy
Facts about the device go into every issuance decision as XACML environment
attributes. The built-in role-issuance policy decides on them, and a realm’s
own policy can too (XACML):
| Attribute | Value |
|---|---|
urn:sts:xacml:device-recognized |
a boolean |
urn:sts:xacml:device-id |
the register’s id |
urn:sts:xacml:device-via |
x509, webauthn, jwk or native-sso |
urn:sts:xacml:device-owner-matches |
a boolean: the device is the subject’s own |
urn:sts:xacml:device-owner-kind |
person or application |
urn:sts:xacml:device-compliance |
compliant, not-compliant or unknown |
urn:sts:xacml:device-attestation |
attested or self-asserted |
urn:sts:xacml:device-status |
active or compromised |
urn:sts:xacml:device-risk-level |
LOW, MEDIUM or HIGH, when assessed |
urn:sts:xacml:device-requirement |
what this realm’s settings require: not-compromised, compliant, attested |
The built-in policy has two device rules. Settings switch them on and off, so no policy edit is needed:
- A compromised device is refused, for every application. This is on by
default in both modes (
devices.refuseCompromised), and the refusal isSTS-DEVICE-0038. A compromise ends the device’s sessions and revokes its certificates and secret, but its JWK and WebAuthn keys still identify it. A token request bound to one of them is exactly what this rule refuses. With the setting off, a compromised device is only a risk signal. - A realm can require a compliant registered device
(
devices.requireCompliantDevice). This is off by default in both modes. While it is on, anything not from the subject’s own compliant, uncompromised device is refused (STS-DEVICE-0037). An application’s device counts too, such as a kiosk or a managed host.- With
devices.compliantDeviceAttestedon, the device must also be attested. - The console and the portal are exempt, because the portal is where a
person registers a device. The template’s
deviceExemptparameter names the exempt applications. - A door that carries no device evidence is refused while the rule is on, for example a Kerberos ticket, or a password grant without DPoP.
- With
The client is told only that authentication failed, or that a compliant registered device is required. The rule and the device are on the audit row.
Somebody else’s device is only a fact: device-owner-matches is false. The
built-in policy refuses nothing for that alone. A person may sign in on a
shared machine, or on a kiosk an application owns. A realm that wants to
refuse it writes that rule.
Tokens and the acr
device_id is a private claim in the ID Token and the access token (JWT
and introspection). It is present when a registered device was recognised
and that device is the token subject’s own:
- Whose device: a person’s own, or an application’s own device on a
client_credentialstoken. - Which device: the one the token request proved (a DPoP key, a client certificate or a Native SSO secret). If the request proved none, it is the device the session’s sign-in recognised.
-
Its value follows the client’s subject type:
Client subject type device_idpublic the register’s id, the same subSSF names the device bypairwise derived for the client’s sector, so two clients cannot join their records on it ephemeral none, because a stable device id would link one authentication to the next claims_supportedlists it. UserInfo does not return it: it describes the authentication, not the person, just asacr,amrandsiddo.
Where the device’s key is also the token’s binding key, the existing cnf
already names it:
- a DPoP
jktis the device JWK’s RFC 7638 thumbprint; - a certificate is its
x5t#S256.
No second confirmation is added.
urn:sts:acr:compliant-device is published in acr_values_supported,
after 0, 1 and mfa.
- What meets it: an authentication from the person’s own registered
device, compliant and not compromised. With
devices.compliantDeviceAttestedon, the device must also be attested. - Where it sits: it describes where the authentication came from, not
how many factors it had. It neither meets nor is met by
mfa. - A session without such a device: a request for it is sent to sign in
once more, and then refused with
unmet_authentication_requirements(RFC 9470). - A session that meets it: its tokens carry it as their
acr.
Development and product mode
Registration and recognition behave the same in both modes, with one
difference: product refuses a key a device or its owner presents without
an attestation that verified and chained to a trusted root (a portal key
proof, a linked WebAuthn credential, an EST or SCEP device certificate);
development registers it as self-asserted. An administrator’s key entered by
value is accepted in both, recorded as self-asserted. The compliance test
control is open in development only; product refuses it
(STS-DEVICE-0035), and the MDM feed under device:compliance is the door.
Attestation trust
| Statement | Trusted roots |
|---|---|
| Android Key Attestation | devices.androidAttestationTrustAnchors, or Google’s published hardware attestation roots, shipped with the service and pinned by SHA-256 |
| Apple App Attest | devices.appleAppAttestTrustAnchors, or the Apple App Attestation Root CA, shipped and pinned |
| TPM key attestation | devices.tpmTrustAnchors — nothing shipped |
| WebAuthn | the FIDO Metadata Service import and webauthn.attestationTrustAnchors |
A statement that does not verify is refused; one that verifies and chains to none of these is self-asserted. Protocols → Device registration lists the shipped roots by subject and fingerprint.
Configuration
Drawn on Protocols → Device registration; the live source is that page and
GET /admin-api/config.
| Setting | Environment | Default | Runtime | What it does |
|---|---|---|---|---|
devices.maxPerPerson |
STS_DEVICES_MAX_PER_PERSON |
20 |
yes | Devices one person owns. A Native SSO sign-in at the bound replaces the least recently used device whose session has ended; an administrator’s registration is refused. It was oauth2.maxDevicesPerPerson. |
devices.maxPerApplication |
STS_DEVICES_MAX_PER_APPLICATION |
1000 |
yes | Devices one application owns; a registration at the bound is refused. |
devices.maxKeysPerDevice |
STS_DEVICES_MAX_KEYS_PER_DEVICE |
10 |
yes | Keys one device holds. |
devices.eventsKept |
STS_DEVICES_EVENTS_KEPT |
5000 |
yes | Registrations, removals, evictions and compliance changes kept for Monitoring → Devices. |
devices.complianceFeedMaxReports |
STS_DEVICES_COMPLIANCE_FEED_MAX_REPORTS |
500 |
yes | The most reports one POST /admin-api/device-compliance may carry. |
devices.challengeTtlSeconds |
STS_DEVICES_CHALLENGE_TTL_SECONDS |
300 |
yes | How long an enrolment challenge may be answered. |
devices.maxChallenges |
STS_DEVICES_MAX_CHALLENGES |
10000 |
yes | Unanswered enrolment challenges held per realm. |
devices.androidAttestationTrustAnchors |
STS_DEVICES_ANDROID_ATTESTATION_TRUST_ANCHORS |
(empty: Google’s) | yes | Android Key Attestation roots, replacing the shipped ones. |
devices.androidMinimumSecurityLevel |
STS_DEVICES_ANDROID_MINIMUM_SECURITY_LEVEL |
trusted-environment |
yes | trusted-environment or strongbox. |
devices.appleAppAttestTrustAnchors |
STS_DEVICES_APPLE_APP_ATTEST_TRUST_ANCHORS |
(empty: Apple’s) | yes | App Attest roots, replacing the shipped one. |
devices.appleAppAttestAppIds |
STS_DEVICES_APPLE_APP_ATTEST_APP_IDS |
(empty) | yes | TEAMID.bundle.id of the apps whose keys are registered; empty accepts none. |
devices.appleAppAttestAllowDevelopment |
STS_DEVICES_APPLE_APP_ATTEST_ALLOW_DEVELOPMENT |
false |
yes | Accept App Attest’s development environment. |
devices.tpmTrustAnchors |
STS_DEVICES_TPM_TRUST_ANCHORS |
(empty) | yes | TPM manufacturer or AK CA roots. |
devices.lastUsedResolutionSeconds |
STS_DEVICES_LAST_USED_RESOLUTION_SECONDS |
60 |
yes | How often a recognised device’s last use is written. |
devices.expectRegistered |
STS_DEVICES_EXPECT_REGISTERED |
false |
yes | Makes unregistered-device fire for anybody, not only people who registered a device. |
devices.refuseCompromised |
STS_DEVICES_REFUSE_COMPROMISED |
true |
yes | Refuses anything asked for from a compromised device. |
devices.browserDevices |
STS_DEVICES_BROWSER_DEVICES |
true |
yes | Offers “Remember this browser” and reads the cookie. Off: no browser is remembered and a cookie already issued is not read. |
devices.browserTokenLifetimeDays |
STS_DEVICES_BROWSER_TOKEN_LIFETIME_DAYS |
180 |
yes | How long a remembered browser may go unused before it is forgotten (1–400). |
devices.browserReissueGraceSeconds |
STS_DEVICES_BROWSER_REISSUE_GRACE_SECONDS |
60 |
yes | How long the previous token is still accepted after a reissue (two tabs); older is a copied cookie. |
devices.browserTokenCertificateHeader |
STS_DEVICES_BROWSER_TOKEN_CERTIFICATE_HEADER |
x5u |
yes | The certificate header on the signed token. x5c and both make it too large for a cookie. |
devices.requireCompliantDevice |
STS_DEVICES_REQUIRE_COMPLIANT_DEVICE |
false |
yes | Requires the subject’s own compliant registered device. The console and the portal are exempt. |
devices.compliantDeviceAttested |
STS_DEVICES_COMPLIANT_DEVICE_ATTESTED |
false |
yes | A compliant device must also be attested, both for the rule above and for the acr. |
In the running service
- Directory → Devices (
/admin/devices,GET /admin-api/devices): the register, paged and filtered, with a page per device. - Directory → As the directory holds it → Device entries
(
/admin/ldap/devices,GET /admin-api/ldap/devices): the entries attribute by attribute, and the schema. - Protocols → Device registration (
/admin/device-registration,GET /admin-api/device-registration). - Monitoring → Devices (
/admin/devices/monitor,GET /admin-api/devices/monitor): counts by owner kind, compliance, attestation, key kind, attestation format and risk level, registrations, removals, evictions and compliance changes by source day by day, and — counted by the node serving the page — recognitions by kind, enrolments by method and attestation outcomes.
Every operation is in the OpenAPI document at GET /admin-api/openapi.json.
Related
LDAP schema · OAuth 2.0 and OpenID Connect · Shared Signals · CAEP events · Risk scoring · XACML · Management API · Configuration