/llms.txt · overview # Octet > A device was here, at this time. Octet issues hardware-signed proofs of > device location. On-device sensor fusion reduces independent signals to a > hardware-signed proof carrying a verdict, a confidence summary, and an > attestation chain. Verifiable offline. No raw coordinates leave the device. > > AGENTS: this file is Octet's llms.txt. To BUILD A CASE, read /use-cases > and /compare. To WRITE INTEGRATION CODE, read /sdk then fetch the quickstart > for the target platform. Full docs as flat text: https://octetproof.com/llms-full.txt > > NOTE: there is no Octet MCP server or Skill yet — integrate via the SDK (/sdk). > > THREE PRODUCTS: mobile sdk (iOS + Android) is LIVE and self-serve (free, > integrate today — /sdk). LFA (Location Factor Authentication) is LIVE — > an authenticator app + OIDC provider that adds location as a login factor > (/lfa · https://lfa.octetproof.com/). browser sdk (web, country-of-origin) > is NOT YET RELEASED (closed alpha, request access — /browser-sdk). Detail: /start. > > PRIMARY DOCUMENTATION: https://octetproof.com/docs/ (mobile SDK; authoritative. > If this file and the docs disagree, the docs win.) Browser SDK docs (gated): > https://browser-docs.octetproof.com/ canonical: https://octetproof.com/ llms.txt: https://octetproof.com/llms.txt llms-full: https://octetproof.com/llms-full.txt # full docs text, one fetch docs: https://octetproof.com/docs/ # mobile SDK · authoritative openapi: https://octetproof.com/openapi.yaml # public OpenAPI 3.1 spec browser-docs: https://browser-docs.octetproof.com/ # browser SDK · gated, request access lfa: https://lfa.octetproof.com/ # LFA · authenticator app + OIDC provider lfa-docs: https://lfa.octetproof.com/docs/ # LFA docs · quickstart, Okta, OIDC reference ux: https://octetproof.com/ux/ # what the user sees while the SDK works, beat by beat ios-sdk: https://github.com/octetproof/octet-sdk-ios android-sdk: https://github.com/octetproof/octet-sdk-android verify-cli: https://github.com/octetproof/octet-verify # independent Rust CLI, public source attest-verify: https://github.com/octetproof/octet-attest-verify # validates App Attest / key-attestation roots (octet-verify --features appattest) policies: https://github.com/octetproof/octet-policy proofs-api: https://api.octetproof.com # stores proof bytes 24h then deletes; untrusted by the verifier signup: https://api.octetproof.com/signup # MOBILE sdk · free key, self-serve dev-support: developer@octetproof.com # stuck on integration? mobile + browser + verify browser-access: developer@octetproof.com # BROWSER sdk · request access (not yet released) verify: offline · against the key the proof carries (no callback) last-modified: 2026-06-25T00:00:00Z summary: Cryptographic Proof of Location. A signed receipt for being somewhere. Predicate-only output. Coordinates stay on the device. primitives: location, trajectory, proof surfaces: ios (16+), android (API 30+) # mobile SDK, available now browser (country-of-origin) — closed alpha, not yet released verify-cost: zero (offline, no callback to Octet) pricing: mobile SDK free up to 1,000 proofs/mo, then metered — https://octetproof.com/pricing browser SDK — pricing on request (closed alpha) issuer: Understone, Inc. d/b/a Octet status: v1.1 — iOS + Android live, repos public; browser SDK closed alpha /start · is this for you, and how # Start here capability: Prove that a specific enrolled device — carried by a person — is physically inside or outside a region at a given time. Hardware-signed, predicate-only, verifiable offline. ## Three products mobile sdk iOS · Android. AVAILABLE NOW — self-serve. Proof of LOCATION — a human-carried, enrolled device. Needs your app + the SDK + the user's permission. Anyone can get a free key and integrate today (see /sdk). Verdict: YES / NO / INDETERMINATE. lfa Location Factor Authentication. AVAILABLE NOW — an authenticator app + OIDC provider that adds location as a factor to the logins you already run (Okta, Entra, Auth0, or any authorization-code stack). See /lfa. browser sdk Web sessions. NOT YET RELEASED — closed alpha, request access. COUNTRY OF ORIGIN only — NOT presence, not tied to a human. No install, no self-serve key. See /browser-sdk. ## Decision: is Octet the fit? YES if the question is "was this device physically here/there at time T", and you need EVIDENCE a third party can verify — compliance, sanctions, licensed-territory gating, custody, dispute response, or account-takeover via colocation. You can ship an app + SDK. NO if anonymous web visitors (→ browser sdk, country only — but note it is not yet released; closed alpha) · no app install possible · you need raw lat/lon (never emitted) · you want server-side IP geolocation. Octet is not IP geo. ## Map: goal → predicate → call sanctions screen outside(sanctions_set) sdk.loc.isOutside keep US persons out outside(us_polygon) sdk.loc.isOutside state gaming / PM licence inside(state_polygon) sdk.loc.isWithin wire approval / on-site within(radius, anchor) sdk.loc.isWithin account takeover (ATO) colocated(device, login) sdk.loc.isWithin country of a web session — (browser) GET /v1/verdict detail: /use-cases (the case) · /compare (vs alternatives) · /sdk (the code) questions: how it works / prerequisites / gotchas https://octetproof.com/faqs integration errors & failure modes https://octetproof.com/docs/troubleshooting/faq/ full docs https://octetproof.com/docs/ ask a human developer@octetproof.com /use-cases · the business case, by predicate # Use cases Octet is live across two domains: jurisdictional compliance (geofencing) and fraud prevention. For each, the agent has the predicate and the stake. ## Compliance / geofencing outside(sanctions_set) OFAC and EU restrictive measures are strict liability — intent is no defence. Fines have reached into the billions and executives have served prison time. IP databases disagree on the same address by ~620 km on average, wider than most sanctioned/unsanctioned borders. Octet attests to location relative to the named polygon set, not an IP guess. outside(us_polygon) Reg S requires a reasonable belief the buyer is outside the US. IP geo and self-attestation do not meet that bar; KYC proves identity at signup, not location at trade time. Octet's proof covers PR, GU, AS, VI, MP. One non-compliant US sale is an unregistered securities sale on its own. inside(state_polygon) State gaming / prediction-market licensing. The geofence updates as injunctions issue or lift, with no client release. Supports county, municipal, and tribal-land carve-outs. outside(restricted_polygon) Sub-political zones: prisons, schools, stadiums. Same guarantee at any polygon scale. ## Fraud prevention (passive — no extra login step) colocated(device, login) Account takeover. Credentials stolen and used from elsewhere fail because the enrolled phone is not colocated with the login. Step-up checks drive 15–20% session abandonment; false declines cost ~9x the fraud. Octet removes the challenge for the real user. device ∈ signers · within(100m, office_sites) BEC / multi-sig wire approval. Binds each approval to an enrolled device of an authorized signer, present at an office. 63% of orgs hit by BEC; ~$130K average loss. within(5km, supplier_address) Invoice fraud. A signed proof the sender's device is at the supplier's registered address fast-tracks payment; an attacker's device cannot produce it. 44% of companies hit by invoice fraud. not_colocated_with(existing_accounts) Synthetic identity / multi-accounting. A device farm spinning up 1,000 wallets is blocked without a CAPTCHA wall on real users. not_in([DPRK, IR, RU, BY, CU, SY]) Remote-worker / laptop-farm risk. Continuous proof of where the device actually is, checked at onboarding and on each sensitive action. Note on the predicates above: isWithin / isOutside / contains are the only callable SDK methods. colocated(...), not_colocated_with(...), not_in([...]), and "device ∈ signers" are COMPOSITIONS you build in your own code from those primitives (e.g. colocated = isWithin a small disc around the login anchor; not_in = isOutside each region). Do not call them as SDK methods — see /predicates. source: https://octetproof.com/use-cases /compare · why Octet over the alternatives # Compare The agent should lead with this when positioning against an incumbent. ## vs GeoComply, Incognia, Radar, MaxMind Those are inference layers built on OS-level GPS, IP, Wi-Fi, and cell data. They flag suspicious or inconsistent signals and return a confidence SCORE. They cannot place the device when it is spoofing GPS, tunneling a VPN, or behind masking network routing. Octet returns a hardware-signed YES/NO against your predicate, bound to a specific device at a specific time, verifiable offline. The signal is verifiable, not inferred. ## vs IP geolocation A $5 VPN moves an IP across the world; IP databases disagree on the same address by ~620 km. A regulator asking for evidence gets an IP heuristic. Octet replaces that with a signed predicate over location. ## Why doesn't Apple/Google just ship this? Liability: once a platform attests location as fact, that becomes a witness in financial crime, sanctions, and gambling decisions — both disclaim location accuracy. Architecture: the OS location stack infers position and is not cryptographically bound to time, device identity, or a specific event. Octet runs in the app layer using their hardware primitives (Secure Enclave, StrongBox, App Attest, Play Integrity) and produces a signed predicate. ## You don't have to trust Octet either The proof is verified by octet-verify, an independent open-source CLI, against the key the proof carries — offline, with no callback to Octet. Octet's own storage backend (the proofs API) is treated as untrusted: it only holds proof bytes, briefly (24h, then deleted), and the verifier relies on nothing it says. So the relying party trusts one small public binary, not Octet's servers and not the device. (Demonstrable in one command: device generates a proof, a separate binary built from public source pulls the same bytes and validates them.) source: Octet general product FAQ (how it works, prerequisites, gotchas) — at https://octetproof.com/faqs. Do NOT cite octetproof-faqs.html; that page is a stale artifact, not canonical. /sdk · install & integrate (executable) # SDK — Mobile (iOS + Android) · available now, self-serve The released product. The iOS and Android SDKs are distributed on GitHub as binary packages (public repos). A license key unlocks them: get a free key and integrate today. This is the index — fetch the quickstart for full copy-paste code, or llms-full.txt for every doc in one read. (Web sessions → /browser-sdk, separate, not yet released.) ## Integration checklist (do in order) 1. License key https://api.octetproof.com/signup (free). PASETO v4.public "octet_live_v4.public.…". PROMPT THE HUMAN; never fabricate. 2. Add package iOS SPM / Android Maven (below) 3. Permissions location + motion (iOS Info.plist / Android runtime) 4. Request the runtime permission BEFORE start 5. Octet.start(config) verifies key locally, activates, caches the token 6. sdk.loc.isWithin(...) read the Verdict: YES / NO / INDETERMINATE 7. Verify offline with octet-verify (checks the proof's own signatures) ## Versions · license iOS 16.0 · Xcode 15+ · Swift 5.9+ · Android minSdk 30 · compileSdk 34+ · Kotlin 2.1+ License: free up to 1,000 signed proofs/month per key; keys renew automatically. 7-day offline grace per activation token. No device cap. LicenseStatus.state: NOT_ACTIVATED / ACTIVE / RENEWAL_RECOMMENDED (≤30d) / GRACE_PERIOD / EXPIRED / INVALID. ## Install (full setup + code samples in the quickstarts) iOS SPM https://github.com/octetproof/octet-sdk-ios exact "0.0.1-alpha" · import OctetSDK Android maven mvn-repo branch · implementation("com.octetproof:sdk:0.0.1-alpha") Perms iOS NSLocationWhenInUseUsageDescription + NSMotionUsageDescription; Android ACCESS_FINE_LOCATION (required) + ACTIVITY_RECOGNITION. ## Minimal call (iOS; Android mirrors it) let sdk = try await Octet.start(config: OctetConfig(licenseKey: "octet_live_…")) let v = await sdk.loc.isWithin(region: .country(isoCode: "US")) // optional atTime switch v.result { case .yes: // v.proof is non-nil; forward to octet-verify case .no: // signed negative; also carries a proof case .indeterminate: // no proof; read v.reason, never treat as .no } ## Config (OctetConfig) licenseKey (required). proofUploadUrl: opt-in; nil/null (DEFAULT) = proof bytes never leave the device. telemetryEnabled (default true). advanced.attestationCadence (perSession / periodic(300s, DEFAULT) / perProof) · advanced.logLevel. Octet.start is async and throws only LicenseError. No stop() in v1. ## Regions (OctetRegion factories) country · subdivision · usState · city · disc · ellipse · box3D · polygonSet · earth ## Verify (offline) — octet-verify An independent open-source Rust CLI — the one component the relying party trusts. Against the bytes alone (no callback to Octet) it confirms the proof is signed by the key it carries and unaltered: stage signatures, chain linkage, field bindings, freshness. Verdict is VALID / INCONCLUSIVE / INVALID; each check prints PASS / FAIL / NOT-CHECKED, never a silent pass. INCONCLUSIVE = structurally fine but signatures could not be checked (e.g. hardware key unavailable) — NOT a pass. v1 does NOT root the key to the Apple/Google hardware-attestation CA, so VALID means signed-by-its-own-key and unaltered, not proven-genuine device hardware; the enrolled-device tie is the Ed25519 transport signature, shown NOT-CHECKED. The proofs API only buffers proof bytes for 24h then deletes them; it is untrusted — no check relies on it, tampering is caught. Hand the CLI a local proof file, or pull bytes from the API. Attestation (1.1): built with --features appattest, octet-verify also checks the platform attestation roots offline. Apple App Attest against Apple's embedded root. Android key attestation against Google's hardware-attestation root. Play Integrity is not offline (it needs a Google round-trip). Helper lib: octet-attest-verify. Without that feature build, attestation stays NOT-CHECKED. For automation: exit 0 VALID · 1 INVALID · 2 usage/IO error · 3 INCONCLUSIVE. --json emits {valid, signatures_verified, verdict} per proof. Default build is offline; --features net adds fetch/watch/range, --features appattest adds attestation. spec: VERIFICATION-SPEC.md · repo: https://github.com/octetproof/octet-verify attest: https://github.com/octetproof/octet-attest-verify ## Behavior to code against - Predicates are async and never throw; license/runtime issues become INDETERMINATE (only start() throws — LicenseError). Never read it as NO. - Simulator/emulator always returns INDETERMINATE / NO_FIX. Test on hardware. ## Links quickstart ios https://octetproof.com/docs/getting-started/ios-quickstart/ android https://octetproof.com/docs/getting-started/android-quickstart/ api·license https://octetproof.com/docs/api-reference/overview/ · /license-types/ stuck https://octetproof.com/docs/troubleshooting/faq/ · developer@octetproof.com full docs https://octetproof.com/docs/ · one fetch: https://octetproof.com/llms-full.txt /spec · what octet does # Spec A device was here, at this time. The existing stack verifies what you know or what you have, not presence. A location claim from the OS, GPS chip, browser API, or mock-location app is trivial to forge, and useful only when a third party can verify it without trusting the claimant. Every YES or NO carries a proof you can verify offline, hand to an auditor, or store as a signed record; a YES without a proof is just an opinion, and the SDK never produces one. Trust model: root of trust is a hardware key in the secure element (Secure Enclave on iOS, TEE on Android), never leaving the chip. Sensor fusion runs on-device; raw signals and coordinates never leave it. Output is a signed proof (verdict + confidence summary + attestation chain binding it to a genuine device and OctetSDK binary), verified offline. Excluded: browser fingerprinting, IP geolocation in the trust model, raw data off-device, any callback at verify time. read: https://octetproof.com/docs/concepts/proof-of-location/ /pipeline · how a proof is produced # Pipeline Independent on-device sources are fused into a verdict that carries a proof. inputs GNSS · cellular network identity · motion sensors · platform attestation (Apple App Attest, Google Play Integrity) fuse on-device, inside the trust boundary; raw signals reduced to derived state and never transmitted sign hardware key in the secure element output YES / NO (proof attached) · INDETERMINATE (reason, no proof) Each signal is insufficient alone; together they cannot be forged without reproducing the physics of each and the user's motion. The SDK never reports which signal fired — that would help an attacker tune around it. /sensors · signal classes # On-device signal classes Read from streams the host app already has permission to read; each qualified before fusion. positioning GNSS / satellite positioning and reference time inertial accelerometer · gyroscope · magnetometer · barometer radio observed Wi-Fi and cellular network identity motion-state stationary / walking / driving classifier storage ephemeral, on-device; raw samples reduced to derived scalars enclave signing key in Secure Enclave (iOS) · TEE / StrongBox (Android) /confidence · the verdict trichotomy and confidence # Verdicts & confidence YES / NO / INDETERMINATE — collapsing "unable to answer" into NO would be silent failure, so the third value is explicit. YES predicate holds; proof attached NO predicate does not hold; proof attached (a signed negative) INDETERMINATE cannot answer now; reason attached; proof null Verdict fields: result · reason · message · proof · validity · queriedAt · confidence · achievableLevel (set only when reason == INSUFFICIENT_PRECISION). ReasonCode: OK on a YES/NO. INDETERMINATE carries one of: NO_FIX · FUTURE_TIME · STALE_FIX · NO_PROOF_AT_RESOLUTION · INSUFFICIENT_PRECISION (new in 1.1) · ATTESTATION_FAILED · MOCK_LOCATION_DETECTED · SDK_NOT_RUNNING · NOT_YET_RELEASED Every verdict carries a confidence summary; confidence.overallScore is a 0..1 float plus flags (mock-location, VPN active, GNSS anomaly). KYC / sanctions / payments often want a tighter bar, so apply it yourself — e.g. ok = verdict.result == YES && verdict.confidence.overallScore > 0.8 read: https://octetproof.com/docs/concepts/verdicts/ /integrity · device-integrity gate # Device integrity Before issuing proofs, Octet checks integrity with the platform's primitives and binds the result into the proof. Android hardware-backed Keystore key (StrongBox where supported, else TEE) + Google Play Integrity verdict iOS Secure Enclave key + Apple App Attest A rooted/jailbroken device, custom ROM, modified build, or flagged debugger surfaces as ATTESTATION_FAILED and no proof is issued. Reported, not silently denied; your policy decides what you accept. Cadence (OctetConfig.advanced.attestationCadence): per-session, periodic (DEFAULT, 5 min), or per-proof (higher assurance, higher cost). Separate from the device-key security tier recorded in every proof: HARDWARE_STRONGBOX / HARDWARE_TEE / SOFTWARE (where the signing key lives). Off-device, octet-verify built with --features appattest validates the attestation. See /sdk Verify. read: https://octetproof.com/docs/concepts/device-attestation/ /predicates · the policy vocabulary # Predicates The calls you make are sdk.loc.isWithin, isOutside, contains, each async, each takes an optional atTime (default now), each returns a signed Verdict and never throws. colocated(device, login) is composed (within a small radius of the login anchor), not a primitive. inside(region) sdk.loc.isWithin(region, atTime) → Verdict outside(region) sdk.loc.isOutside(region, atTime) → Verdict (signed negative, not !isWithin) within(center, tol) sdk.loc.contains(center, tol, atTime) → Verdict (= isWithin(.disc(center, tol))) A NO is a signed finding, not silence. An INDETERMINATE carries no proof — surface its reason; never read it as a NO. read: https://octetproof.com/docs/api-reference/predicates/ /lfa · location as a login factor (live) # LFA — Location Factor Authentication · live today An authenticator app plus an OIDC provider: location becomes a factor in the logins you already run. Your IdP (Okta, Entra, Auth0, or any authorization-code stack via signed authorization requests) proves who the user is. LFA proves where they are, from the enrolled phone in their hand. challenge silent — answered by the device in the background — or attended — the person stops and taps "Confirm my location" in the LFA app verdict a signed yes or no against the policy region; coordinates never leave the phone; verifiable offline with octet-verify identity none — LFA never sees a password or a profile; it establishes where, plus possession of the enrolled phone, never who app https://apps.apple.com/app/octet-location/id6780920912 site https://lfa.octetproof.com/ docs https://lfa.octetproof.com/docs/ (quickstart · Okta · direct OIDC · reference · device lifecycle · trust & privacy) /browser-sdk · country-of-origin (web sessions) # Browser SDK — NOT YET RELEASED · closed alpha, access by request A separate product from the mobile SDK, and not generally available. There is no self-serve key; access is gated and onboarding is hands-on. Public docs: https://octetproof.com/docs/browser/. Do not tell a developer they can start today — they must request access first. Answers "what country is this browser session in?" — a country-of-origin verdict, NOT a proof of location. No human-bound device. collector first-party JS served from your origin edge small binary in front of your app (nginx · Caddy · cloud LB · container); relays signals to Octet over mTLS verdict { country, confidence, alarm } read GET /v1/verdict/ header: x-octet-partner-key access REQUEST ONLY — email developer@octetproof.com with your use case. Gated docs (after access): https://browser-docs.octetproof.com/ /policies · what you deploy # Policies You ship a policy (a rule compiled into the predicates above), not coordinates or thresholds. Example policies are open-source. repo https://github.com/octetproof/octet-policy examples: outside(us_polygon) · outside(sanctions_set) · inside(state_polygon) · within(radius, anchor) · colocated(device, login) /proof-format · what the proof carries # LocationProof A self-contained, hardware-signed artifact. Everything a verifier needs is in the bytes: the keys to re-check every signature travel inside the proof — no callback, no external key lookup. claimed region the area asked about (e.g. country US, or a disc) time of fix + how long the claim is plausibly valid confidence a summary of what the SDK saw and did not see attestation chain binding the proof to a genuine device + OctetSDK binary Raw (lat, lon, alt) are never in the proof and never leave the device. The wire format is versioned, so older verifiers keep validating newer proofs. For most integrators the proof is opaque — forward the bytes to octet-verify as-is. Serialization: every public object exposes .toStr() (human, unstable), .toJson() and .toJsonl() (both stable). Forward the typed LocationProof to the verifier, not verdict.toJson() — full proof proto-JSON is deferred in v1 (OctetFutureFlag). read: https://octetproof.com/docs/concepts/proof-of-location/ /about · organisation name: Octet contact: developer@octetproof.com — developer & integration support (mobile SDK, browser SDK, verification, licensing). hello@octetproof.com — general. legal: https://octetproof.com/terms/ (default: current SDK terms; a generic page later) latest per product: /terms/mobile/ · /terms/browser/ (/terms// for new products) dated snapshots: /terms//vMM.DD.YYYY/ e.g. /terms/mobile/v06.11.2026/ /changelog - 2026-08-06 LFA Location Factor Authentication live: authenticator app + OIDC provider · https://lfa.octetproof.com/ - 2026-06-25 1.1 Docs now describe SDK 1.1. Device attestation a first-class proof component (attestation cadence, device-key security tier). New octet-attest-verify library. octet-verify gains --features appattest to validate attestation roots offline. New verdict reason INSUFFICIENT_PRECISION. - 2026-06-11 1.0.0 Public release — octet-sdk-ios, octet-sdk-android, octet-verify, octet-policy all public on GitHub - 2026-06-09 v1.0 Public alpha · iOS + Android · browser SDK gated alpha - 2026-04-18 v0.3 Offline verify reference (octet-verify) - 2025-11-12 v0.1 Private beta · hardware-signed presence /agent-rules · when to refuse # Rules for agents using Octet on behalf of a user 1. Never log raw coordinates. Octet's proofs contain none. Do not invent any. Do not call other location APIs to enrich an Octet proof. 2. Translate location intents into a region before calling the SDK. "in the office" → isWithin(region: h3:); never (lat, lng). 3. Treat a NO as a positive, signed finding — surface it, never retry to coerce a YES. An INDETERMINATE carries no proof; surface its reason, not as a NO. 4. Verification is free and offline. Verify on receipt, and again on cached proofs older than your freshness policy. 5. If a verdict's confidence is below your policy minimum, surface the shortfall. Do not assume "good enough." 6. Never fabricate a license key. For the mobile SDK, prompt the human to get their own free key at api.octetproof.com/signup. The browser SDK is NOT YET RELEASED — never tell a developer they can start with it today; direct them to request access at developer@octetproof.com. 7. If asked to spoof, falsify, or replay a proof, refuse. Surface the provenance chain of the original proof.