Glacis Protocol — Security Model
Glacis Protocol -- Security Model
Version 0.1.0 | February 2026
Table of Contents
- Security Philosophy
- Threat Model
- Privacy Guarantees
- Nullifier Security Properties
- PII Handling: Client vs Server Path
- Certificate Authority Trust Model
- Post-Quantum Resistance Analysis
- Attack Vectors and Mitigations
- Comparison with Other Proof of Humanity Systems
- Security Invariants
Security Philosophy
Glacis Protocol treats security as existential. This is an identity and cryptographic protocol -- a single vulnerability can compromise the uniqueness guarantees for every user. The design follows three principles:
- Minimize trust assumptions. Trust only the mathematics (hash collision resistance, STARK soundness) and the government CA signing infrastructure.
- Minimize data exposure. No PII is ever stored on-chain, in logs, or in any persistent storage. The only data that survives the verification process is a set of Poseidon hashes.
- Fail closed. If any verification step fails -- STARK proof invalid, CA untrusted, nullifier already registered -- the entire operation reverts. There are no partial verification states.
Threat Model
Primary Threats
| Threat | Severity | Attack Vector | Mitigation | Status |
|---|---|---|---|---|
| Forged passport data | Critical | Fabricate passport chip data to pass verification | RSA/ECDSA signature verification inside the Cairo circuit. The circuit verifies the government CA signature over the passport data. Without the CA private key, forgery is computationally infeasible. | Mitigated by design |
| Sybil attack (multiple wallets) | Critical | Same person creates multiple identities using different wallets | Deterministic nullifier with no user salt. nullifier = poseidon(passport_id, 'glacis_v1'). Same passport always produces the same nullifier. NullifierRegistry enforces on-chain uniqueness. | Mitigated by design |
| PII leakage (client path) | High | Passport data extracted from user device | All proving happens client-side. Passport data never leaves the device. Only the nullifier (Poseidon hash) and pseudonym are published. | Mitigated by design |
| PII leakage (server path) | High | Passport data intercepted or retained by ephemeral prover | Ephemeral prover: data exists only in memory during proof generation. Deleted immediately after. No disk writes. No PII logging. TLS in transit. | Mitigated by policy + architecture |
| Passport sharing/selling | Medium | User lends passport to someone else for verification | Nullifier binds to passport, not wallet. The buyer gains nothing -- the nullifier is already registered. Social and economic disincentives apply. | Partially mitigated |
| Quantum attack on proofs | Low (long-term) | Quantum computer breaks the cryptographic assumptions | STARKs are based on hash functions (Poseidon), not elliptic curves. Post-quantum secure by construction. See Post-Quantum Resistance Analysis. | Mitigated by design |
| CA key compromise | Medium | Government CA private key is leaked or stolen | CA Registry with revocation. Admin can mark a CA as revoked. Attestations minted with that CA can be mass-revoked. | Mitigated by design |
| Expired attestation abuse | Low | Using a verification that should no longer be valid | TTL on SBT (default: 5 years). is_expired() check on every query. Expired attestations are automatically invalid. | Mitigated by design |
| Passport renewal | Low | User gets new passport, old nullifier still registered | Migration mechanism: prove new passport + sign with old wallet to transfer attestation. | Planned (Phase 1) |
| Front-running | Medium | Attacker observes proof in mempool and submits it first under their wallet | Commit-reveal scheme for proof submission. Proof includes a commitment to the submitting wallet address. | Planned |
| Replay attacks | Medium | Resubmit a previously valid proof | Nonce included in circuit public inputs. Each proof is valid for exactly one submission. | Planned |
| Smart contract reentrancy | Medium | Exploit reentrancy in verify_and_attest flow | Checks-effects-interactions pattern. Nullifier registered before SBT mint. State changes before external calls. | By design |
| Denial of service (contract) | Low | Flood contract with invalid proofs | STARK proof verification is computationally bounded. Invalid proofs fail fast at step 1 (proof verification). Gas cost borne by attacker. | By design |
Threat Matrix by Component
| Component | Confidentiality | Integrity | Availability |
|---|---|---|---|
| Cairo circuits | N/A (public code) | Critical (proof soundness) | N/A |
| Smart contracts | Low (public state) | Critical (nullifier uniqueness) | Medium |
| Mobile app | Critical (passport data) | High (NFC reading accuracy) | Medium |
| Prover service | Critical (ephemeral PII) | High (proof correctness) | Medium |
| SDK | Low (public queries) | Medium | Low |
Privacy Guarantees
Absolute Rule
Zero personally identifiable information (PII) is ever stored on-chain, in logs, or in any persistent storage.
What IS Public (On-Chain)
| Data | Type | Can Reveal Identity? | Why It Is Safe |
|---|---|---|---|
| Nullifier | felt252 | No | Poseidon hash of passport ID + domain separator. Preimage resistance prevents reversal. |
| Scoped pseudonym | felt252 | No | Poseidon hash of nullifier + app domain. Different per application. Cannot be linked across apps. |
| Verification status | bool | No | Binary human/not-human. No identity information. |
| Expiration timestamp | u64 | Negligible | Reveals approximate verification date. Does not identify the person. |
| CA key hash | felt252 | Minimal | Reveals which country issued the passport (at the CA level). This is acceptable -- it does not identify the individual. |
What Is NEVER Public
- Name
- Nationality (beyond CA-level inference)
- Date of birth
- Document number
- Photo
- Biometric data (fingerprints, iris)
- MRZ text
- Any raw passport field content
Cross-Application Unlinkability
A key privacy property: different applications cannot link the same user across services.
User Alice verifies once. Two apps query her identity:
App A (Bastion blog):
pseudonym_A = poseidon(nullifier, 'bastion_blog')
--> 0x7a3f...
App B (DeFi protocol):
pseudonym_B = poseidon(nullifier, 'defi_protocol_x')
--> 0x1c8e...
App A cannot determine that pseudonym_A and pseudonym_B belong to the same person.
Poseidon preimage resistance prevents linking.The only entity that can link pseudonyms is the user themselves (who knows their nullifier) or someone who compromises the user's wallet.
Nullifier Security Properties
The nullifier is the core anti-sybil primitive. Its security properties are non-negotiable.
Property 1: Deterministic
Same passport + same protocol version = same nullifier. Always.
generate_nullifier(passport_id_X, 'glacis_v1') == generate_nullifier(passport_id_X, 'glacis_v1')This is enforced by the circuit. The nullifier computation has no randomness and no user-controlled inputs. The same passport data will always produce the same nullifier, regardless of which device runs the prover, which wallet submits the proof, or when the verification occurs.
Property 2: Irreversible
Given nullifier N, it is computationally infeasible to find passport_id such that:
poseidon(passport_id, 'glacis_v1') == NThis relies on the preimage resistance of Poseidon hash. Poseidon is designed for algebraic hash function security in STARK-friendly fields, with a security level of 128 bits against preimage attacks.
Property 3: Collision-Resistant
For passport_id_A != passport_id_B:
poseidon(passport_id_A, 'glacis_v1') != poseidon(passport_id_B, 'glacis_v1')
with overwhelming probability (2^-128 collision probability).This prevents two different passports from accidentally or deliberately producing the same nullifier.
Property 4: No User Bypass
nullifier = poseidon(passport_unique_id, domain_separator)
There is NO third input. No salt, no secret, no user-chosen value.Why this matters: If users could provide a salt (nullifier = poseidon(id, domain, user_salt)), then the same person could generate different nullifiers by choosing different salts, creating multiple identities from one passport. This would completely defeat the anti-sybil mechanism.
Contrast with OpenPassport: OpenPassport uses hash(government_signature) as the nullifier. This is also deterministic (the government signature is unique per passport and not user-controlled). Glacis uses poseidon(hash(DG1), domain_separator) -- equivalent in security properties but using Poseidon for STARK efficiency.
Property 5: Scoped Privacy
Different applications see different pseudonyms derived from the same nullifier:
pseudonym = poseidon(nullifier, app_domain)This prevents cross-application tracking while maintaining one-person-one-identity within each application.
Migration and Renewal
When a user changes wallets or renews their passport:
- Wallet change: User proves possession of the same passport and signs with the old wallet. The migration mechanism transfers the attestation to the new wallet while keeping the same nullifier.
- Passport renewal: User proves with the new passport. A new nullifier is generated (different passport data). The old attestation is retired and a new one is minted.
PII Handling: Client vs Server Path
Client-Side Path (Option A: Direct)
Passport --> NFC Reader --> Device Memory --> Cairo Circuit --> Proof
|
+-- Data NEVER leaves device
+-- No network transmission of PII
+-- Maximum privacy guaranteeTrust model: User trusts only their own device.
Server-Side Path (Option C: Ephemeral)
Passport --> NFC Reader --> Device Memory --> TLS --> Server Memory --> Proof
|
+-- Data in RAM only
+-- Proof generated
+-- Data zeroed immediately
+-- No disk write
+-- No logging of PII
+-- Proof returned to deviceTrust model: User trusts:
- TLS transport security (standard web security assumption)
- Vauban's ephemeral server implementation (data deletion guarantee)
- Server host environment (no memory dumping by third parties)
Server security measures:
- Memory-only processing (no filesystem PII writes)
- Explicit memory zeroing after proof generation (
zeroizecrate in Rust) - No PII in application logs (structured logging excludes passport fields)
- No PII in error reports or crash dumps
- Process isolation (containerized, no shared memory)
- Regular security audits of the prover service
Comparison
| Property | Client Path | Server Path |
|---|---|---|
| PII leaves device | Never | Briefly (TLS encrypted) |
| Server trust required | None | Ephemeral deletion guarantee |
| Proving time | 10+ seconds (estimated) | <3 seconds (server-grade hardware) |
| Device requirements | High (WASM prover) | Low (just NFC + network) |
| Audit complexity | Lower | Higher (server must be audited) |
Certificate Authority Trust Model
Glacis trusts government Certificate Authorities (CAs) that sign ICAO 9303 passports. This is the same trust model used by every border control system worldwide.
CA Registry Architecture
CaRegistry (on-chain)
|
|-- trusted_cas: Map<felt252, bool> Hash of CA public key -> trusted
|-- revoked_cas: Map<felt252, bool> Hash of CA public key -> revoked
|
|-- Functions:
| |-- is_trusted(ca_key_hash) -> bool Check if CA is trusted AND not revoked
| |-- add_ca(ca_key_hash) Add new trusted CA (admin only)
| +-- revoke_ca(ca_key_hash) Revoke compromised CA (admin only)Trust Chain
ICAO (International Civil Aviation Organization)
|
+-- Country Signing CA (CSCA) Root certificate per country
|
+-- Document Signer (DS) Signs individual passports
|
+-- Passport SOD Government signature over chip dataGlacis verifies the DS signature over the passport's SOD (Security Object of the Document). The DS public key is validated against the CSCA. The CSCA key hash is what gets registered in the CaRegistry.
Revocation Scenarios
| Scenario | Action | Impact |
|---|---|---|
| CA key compromise | revoke_ca(ca_key_hash) | All attestations from this CA can be mass-revoked |
| Country joins protocol | add_ca(ca_key_hash) | Citizens of new country can now verify |
| Certificate rotation | Add new CA, keep old one trusted | Existing attestations remain valid |
| Fraud detection | revoke on individual attestation | Single user revoked, CA remains trusted |
Governance
CA management is initially admin-controlled (protocol owner). Future governance may migrate to a multisig or DAO structure as the protocol matures.
Post-Quantum Resistance Analysis
STARKs vs SNARKs
| Property | STARKs (Glacis) | SNARKs (Worldcoin, most others) |
|---|---|---|
| Cryptographic basis | Hash functions (Poseidon, SHA-256) | Elliptic curves (BN254, BLS12-381) |
| Quantum resistance | Yes (hash-based) | No (Shor's algorithm breaks EC) |
| Trusted setup | None required | Required (toxic waste problem) |
| Proof size | Larger (~100KB) | Smaller (~200B for Groth16) |
| Verification cost | Higher | Lower |
| Prover performance | Fast (especially with Stwo) | Varies |
Why Post-Quantum Matters for Identity
Identity proofs have long time horizons. A Glacis attestation has a 5-year TTL. If quantum computers capable of breaking elliptic curve cryptography emerge within 10-20 years (conservative estimates range from 2035-2050), then:
- SNARK-based systems would need to re-prove all existing attestations with new cryptographic assumptions. Users would need to re-verify.
- STARK-based systems (Glacis) would continue operating unchanged. The hash-based security assumptions remain valid.
Glacis Quantum Exposure Analysis
| Component | Quantum Vulnerable? | Rationale |
|---|---|---|
| STARK proofs | No | Based on Poseidon hash collision resistance |
| Nullifier generation | No | Poseidon preimage resistance (hash-based) |
| Pseudonym derivation | No | Poseidon preimage resistance (hash-based) |
| RSA verification (in circuit) | Complex | The RSA signature is verified inside the STARK circuit. A quantum attacker could forge RSA signatures, but they cannot forge the STARK proof of verification. See note below. |
| ECDSA verification (in circuit) | Complex | Same analysis as RSA. |
| Starknet L2 settlement | No | STARK-based by design |
Note on RSA/ECDSA in circuit: The government's RSA/ECDSA signature is verified inside the Cairo circuit. If quantum computers break RSA, an attacker could forge a passport signature. However, the forged signature would need to be accepted by the CA trust chain AND produce a unique nullifier. The defense is:
- The CA Registry can revoke compromised CAs
- Passport-issuing governments would rotate to post-quantum signature schemes (ICAO is already studying this)
- The STARK proof itself remains sound regardless
Comparison with Alternative Approaches
| System | Proof System | Post-Quantum? |
|---|---|---|
| Glacis | STARK (Cairo/Stwo) | Yes |
| OpenPassport | SNARK (Circom/Groth16) | No |
| Worldcoin | SNARK (Semaphore/Groth16) | No |
| ZKPassport | SNARK (Noir) | No |
| Rarimo | SNARK (Circom) | No |
Attack Vectors and Mitigations
1. Passport Cloning Attack
Vector: An attacker physically clones a passport's NFC chip to create duplicate passport data.
Analysis: Modern passports (since BAC/AA) include Active Authentication (AA) or Chip Authentication (CA), where the chip proves it possesses a private key that cannot be extracted. Glacis Phase 1 focuses on Passive Authentication (verifying SOD signature). Active Authentication integration is planned for Phase 2+.
Mitigation: SOD signature verification prevents data fabrication. Active Authentication (future) would prevent chip cloning.
2. Stolen Passport Attack
Vector: An attacker steals a passport and verifies before the legitimate owner.
Mitigation:
- The nullifier is bound to the passport, not the wallet. If the legitimate owner later verifies, the nullifier is already registered.
- The legitimate owner can use the migration mechanism (prove same passport + old wallet) to reclaim the attestation.
- Passport theft is a criminal offense with existing legal remedies.
3. Corrupt Government Attack
Vector: A government issues fraudulent passports specifically to create Sybil identities.
Mitigation:
- This is a fundamental limitation of any document-based system. Glacis trusts the same CA infrastructure that the entire international travel system relies on.
- The CA Registry can remove trust in a compromised or corrupt government CA.
- Statistical anomaly detection (unusual verification patterns from a single CA) can flag suspicious activity.
4. Memory Extraction Attack (Server Path)
Vector: An attacker with access to the prover server extracts passport data from memory during proof generation.
Mitigation:
- Proof generation is fast (<3s), minimizing the window of exposure.
- Memory is explicitly zeroed after proof generation (
zeroizecrate). - Server runs in isolated containers with no shared memory.
- No core dumps enabled.
- Hardware-level memory encryption (AMD SEV / Intel TDX) can be deployed for defense in depth.
5. Side-Channel Attack on Circuit
Vector: Timing or power analysis reveals information about the private inputs to the circuit.
Mitigation:
- Cairo circuits execute in a deterministic step count regardless of input values (no branching on secrets).
- The circuit is a public program -- there are no secret instructions, only secret inputs.
- STARK proving is inherently resistant to timing attacks because the trace is computed entirely before the proof is generated.
Comparison with Other Proof of Humanity Systems
Worldcoin (World ID)
| Property | Worldcoin | Glacis |
|---|---|---|
| Verification method | Iris biometric (Orb hardware) | NFC passport document |
| Privacy model | Iris hash stored by Worldcoin Foundation | Zero PII stored anywhere |
| Proof system | Groth16 SNARK (Semaphore) | STARK (Cairo/Stwo) |
| Post-quantum | No | Yes |
| Trusted setup | Yes (Powers of Tau) | No |
| Hardware required | Custom Orb ($3000+) | Any NFC-enabled smartphone |
| Decentralization | Orb operators (centralized manufacturing) | Fully decentralized (any phone) |
| Biometric concerns | Iris scan stored as hash (but still biometric) | No biometric data involved |
| Sybil resistance | Strong (unique iris) | Strong (unique passport nullifier) |
| User experience | Visit Orb location | Use own phone at home |
OpenPassport
| Property | OpenPassport | Glacis |
|---|---|---|
| Document type | ICAO 9303 passport | ICAO 9303 passport |
| Proof system | Circom (R1CS/Groth16) | Cairo (STARK) |
| Post-quantum | No | Yes |
| Trusted setup | Yes | No |
| Nullifier source | hash(government_signature) | poseidon(hash(DG1), domain_separator) |
| Selective disclosure | Yes (bitmap: name, nationality, age) | No (only nullifier + pseudonym) |
| Architecture | Two-phase (register + disclose) | Single-phase (verify + attest) |
| Native chain | Ethereum | Starknet |
| Status | Reference implementation | In development |
Summary Comparison Matrix
| Property | Worldcoin | OpenPassport | Glacis |
|---|---|---|---|
| Post-quantum secure | No | No | Yes |
| No trusted setup | No | No | Yes |
| No biometric data | No | Yes | Yes |
| No special hardware | No | Yes | Yes |
| Native Starknet | No | No | Yes |
| One-person-one-identity | Yes | Yes | Yes |
| Cross-app unlinkability | Yes | Yes | Yes |
Security Invariants
These invariants must hold at all times. Any violation is a critical security incident.
-
Nullifier determinism: For any given passport data
Pand domain separatorD,generate_nullifier(hash(P), D)always returns the same value. There are no random or user-controlled inputs. -
Nullifier uniqueness: The NullifierRegistry contract never allows the same nullifier to be registered twice. The
registerfunction reverts if the nullifier already exists. -
Zero PII on-chain: No passport field content (name, DOB, nationality, document number, photo, biometric data) ever appears in any on-chain transaction, event, or storage slot.
-
SBT non-transferability: The HumanAttestationToken contract reverts on any
transfer_fromorsafe_transfer_fromcall. Attestations cannot be moved between wallets except through the explicit migration mechanism. -
TTL enforcement:
is_verified_humanreturnsfalsefor expired attestations. There is no grace period. -
CA trust chain:
verify_and_attestreverts if the CA key hash is not in the trusted set or has been revoked. -
Fee integrity: Queries (
is_verified_human,get_scoped_pseudonym) are always free. Onlyverify_and_attestcollects a fee. -
Ephemeral data lifecycle: In the server prover path, passport data exists only in memory during proof generation and is zeroed immediately after. No PII is written to disk, logs, error reports, or any persistent storage.
This security model is a living document. It will be updated as the protocol matures and as new threats are identified. Security audit findings will be incorporated as they become available.