# BitChat Trust Verification System and Vouch Attestations Explained

> Explore BitChat's trust verification system and how vouch attestations work. Learn how verified peers build trust through cryptographic endorsements without direct confirmation.

- Repository: [permissionlesstech/bitchat](https://github.com/permissionlesstech/bitchat)
- Tags: deep-dive
- Published: 2026-08-07

---

**BitChat implements a layered trust model combining explicit user verification with transitive vouch attestations, where verified peers can cryptographically endorse others to establish trust without direct confirmation.**

The permissionlesstech/bitchat repository implements a sophisticated decentralized identity system designed for mesh messaging. The **trust verification system** relies on [`SecureIdentityStateManager.swift`](https://github.com/permissionlesstech/bitchat/blob/main/SecureIdentityStateManager.swift) as its central authority, managing both direct verification and the propagation of trust through **vouch attestations**. This architecture enables users to build transitive trust networks without requiring centralized identity providers.

## How Explicit Verification Works in BitChat

Direct verification forms the foundation of BitChat's trust hierarchy. When a user manually confirms another peer's identity, the system records this decision cryptographically and durably.

### Storing Verified Fingerprints

The `SecureIdentityStateManager` maintains verified state in `cache.verifiedFingerprints`, implemented as a `Set<String>` for O(1) lookups:

- **`setVerified(_:verified:)`** (lines [71-99](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L71-L99)): Adds or removes a fingerprint from the verified set
- **`isVerified(_:)`**: Returns boolean verification status
- **`getVerifiedFingerprints()`**: Enumerates all verified identities

Each verification event also records a timestamp in `cache.verifiedAt`. Upon verification, the associated social identity's `trustLevel` upgrades to **`.verified`** (lines [86-90](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L86-L90)).

```swift
let manager = SecureIdentityStateManager(keychain)
manager.setVerified(fingerprint: "a1b2c3…", verified: true)

```

## Vouch Attestations: Transitive Trust in BitChat

**Vouch attestations** enable trust delegation—allowing a verified user to endorse another peer without requiring the recipient to verify that peer directly. This creates a **web of trust** that scales beyond pairwise connections.

### Recording a Vouch Attestation

The `recordVouch(voucheeFingerprint:voucherFingerprint:timestamp:)` method (lines [124-166](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L124-L166)) enforces strict validation rules:

1. **Reject self-vouches**: A peer cannot vouch for itself
2. **Prevent redundant vouches**: Already-verified peers cannot be vouched for
3. **Voucher authority check**: The voucher fingerprint must exist in `verifiedFingerprints`
4. **Temporal validation**: Timestamp must satisfy `VouchAttestation.maxAge` and `maxClockSkew` constraints

```swift
let voucher = "deadbeef…"  // must be pre-verified
let vouchee = "feedface…"
let ok = manager.recordVouch(
    voucheeFingerprint: vouchee,
    voucherFingerprint: voucher,
    timestamp: Date()
)

```

### Storage and Capping of Vouch Records

Vouches are stored in `cache.vouchesByVouchee` as a per-peer array of `VouchRecord(voucherFingerprint:timestamp:)` structures. The implementation applies two critical limits (lines [111-112](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L111-L112)):

- **Maximum 8 vouchers per vouchee** (`maxVouchersPerVouchee = 8`)
- **Sorted by timestamp**, ensuring recent attestations displace older ones

This bounded storage prevents memory exhaustion attacks and ensures relevance of retained attestations.

### Validating and Querying Vouch Status

BitChat distinguishes between *stored* and *valid* vouches through dedicated methods:

| Method | Location | Purpose |
|--------|----------|---------|
| `validVouchers(for:now:)` | lines [170-178](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L170-L178) | Filters to vouchers still verified and temporally valid |
| `isVouched(fingerprint:now:)` | lines [184-191](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L184-L191) | Returns true if ≥1 valid vouch exists and peer is not explicitly verified |

```swift
if manager.isVouched(fingerprint: targetPeer) {
    // Grant access to vouch-dependent features
}

```

## Trust Level Calculation and Hierarchy

The `effectiveTrustLevel(for:now:)` method (lines [200-227](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L200-L227)) resolves all verification sources into a single authoritative level. Resolution occurs in priority order:

1. **`.verified`** — fingerprint exists in `verifiedFingerprints` (explicit verification)
2. **`.vouched`** — valid vouch exists and no explicit verification (transitive trust)
3. Stored social identity level — `.trusted`, `.casual`, or `.unknown`

The `.vouched` level sits between `.casual` and `.trusted` in the trust hierarchy, granting elevated but not full privileges.

```swift
let level = manager.effectiveTrustLevel(for: peerFingerprint)
// Possible values: .verified, .vouched, .trusted, .casual, .unknown

```

## Vouch Protocol Capabilities and Batch Distribution

BitChat peers advertise protocol support through a capability bitfield defined in [`PeerCapabilities.swift`](https://github.com/permissionlesstech/bitchat/blob/main/PeerCapabilities.swift) (lines [16-22](https://github.com/permissionlesstech/bitchat/blob/main/localPackages/BitFoundation/Sources/BitFoundation/PeerCapabilities.swift#L16-L22)). The `vouch` capability (`1 << 5`) indicates a peer can receive and process vouch attestations.

### Batching and Rate Limiting

The state manager supports efficient vouch propagation through:

- **`mostRecentlyVerifiedFingerprints(limit:excluding:)`** (lines [236-245](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L236-L245)): Returns ordered list for outbound vouch batches
- **`lastVouchBatchSent(to:)` / `markVouchBatchSent(to:at:)`** (lines [232-239](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/Identity/SecureIdentityStateManager.swift#L232-L239)): Tracks batch timing to prevent flooding

## Security Guarantees in BitChat's Trust System

The implementation provides four key security properties:

- **Voucher authority binding**: Only fingerprints in `verifiedFingerprints` may issue valid vouches, preventing arbitrary trust injection
- **Temporal bounds**: `VouchAttestation.maxAge` and `maxClockSkew` prevent replay attacks using stale or future-dated attestations
- **Storage exhaustion protection**: The 8-voucher cap per vouchee bounds memory consumption
- **Encrypted persistence**: All state—including vouches, verification flags, and timestamps—serializes to `IdentityCache` via keychain encryption, ensuring confidentiality at rest and durability across restarts

## Complete Vouch Attestation Workflow

```swift
// 1. Establish verified identity
let manager = SecureIdentityStateManager(keychain)
manager.setVerified(fingerprint: myTrustedContact, verified: true)

// 2. Receive and record vouch for unknown peer
let unknownPeer = "newcomer…"
let recorded = manager.recordVouch(
    voucheeFingerprint: unknownPeer,
    voucherFingerprint: myTrustedContact,
    timestamp: Date()
)

// 3. Query effective trust
if recorded {
    let trust = manager.effectiveTrustLevel(for: unknownPeer)
    print(trust)  // .vouched — elevated from .unknown
}

// 4. Check vouch status specifically
let isVouched = manager.isVouched(fingerprint: unknownPeer)

```

## Summary

- **Explicit verification** stores user-confirmed fingerprints in `cache.verifiedFingerprints` with associated timestamps
- **Vouch attestations** allow verified peers to transitive-trust others through cryptographically signed endorsements
- **`recordVouch()`** enforces strict validation: no self-vouches, verified-voucher requirement, and temporal bounds
- **Storage is capped** at 8 vouchers per peer, sorted by recency
- **`effectiveTrustLevel()`** resolves `.verified` > `.vouched` > stored level, giving the UI and routing layers a single trust signal
- **[`PeerCapabilities.swift`](https://github.com/permissionlesstech/bitchat/blob/main/PeerCapabilities.swift)** defines the `vouch` bit (`1 << 5`) for protocol negotiation
- **All state persists encrypted** via keychain-backed `IdentityCache`

## Frequently Asked Questions

### How does BitChat prevent fake vouch attestations?

BitChat's `recordVouch()` method validates that the voucher fingerprint exists in `cache.verifiedFingerprints` before accepting any attestation. This binding ensures only identities the user has explicitly verified can delegate trust. Additionally, temporal checks using `VouchAttestation.maxAge` and `maxClockSkew` reject replayed or timestamp-manipulated vouches.

### What happens when a peer has multiple vouch attestations?

The `validVouchers(for:now:)` method returns all temporally valid vouches from currently verified peers. However, `isVouched()` and `effectiveTrustLevel()` require only **one** valid vouch to confer `.vouched` status. The `maxVouchersPerVouchee = 8` limit ensures storage remains bounded, with newer vouches displacing older ones.

### Can a vouch attestation expire in BitChat?

Yes. Vouches are validated against `VouchAttestation.maxAge` at query time through `validVouchers(for:now:)`. A vouch older than this threshold becomes invalid even if stored, causing `isVouched()` to return false and `effectiveTrustLevel()` to fall back to the stored social identity level. The original record remains in cache but is filtered during validation.

### How does BitChat advertise vouch protocol support?

Peers declare capabilities through a bitfield in [`PeerCapabilities.swift`](https://github.com/permissionlesstech/bitchat/blob/main/PeerCapabilities.swift). The `vouch` capability (`1 << 5`) signals that a peer can receive and process vouch attestations. This allows negotiation before attempting vouch transmission, preventing protocol errors on incompatible peers.