# MVG Hardware‑Attested Countersign Spec (WebAuthn)

**Version:** v1.0.0  
**Status:** Public (public‑safe, non‑binding)  
**Scope:** Optional, offline‑verifiable evidence that a receipt countersignature was produced using a WebAuthn (FIDO2) credential (platform authenticator or security key).

---

## 1) Why this exists

A normal countersigned MVG receipt can be validated offline with a public key, but it does not prove *where* the private key lived.

This add‑on provides a **hardware‑backed option** using **WebAuthn** so a reviewer can produce a countersignature with a credential that is *typically* backed by:

- **TPM** (Windows platform authenticator)
- **Secure Enclave** (Apple platform authenticator)
- **Hardware security key** (cross‑platform authenticator)

This is meant to be a **deal‑closing evidence artifact**: procurement / security / legal can verify the binding and signature offline, and optionally run their own enterprise attestation trust evaluation.

---

## 2) Guarantees and non‑guarantees

### What this spec guarantees (cryptographically, offline)

When a countersignature uses `signing_method: "webauthn"`, the verifier can check (offline):

1. **Receipt binding:** the WebAuthn `challenge` equals `base64url(SHA‑256(canonical_json(payload)))`.
2. **Signature validity:** the WebAuthn assertion signature verifies against the embedded P‑256 public key.
3. **Relying party binding (rpIdHash):** the `authenticatorData.rpIdHash` matches `SHA‑256(rp_id)` (when `rp_id` is present in the signed payload).
4. **Optional evidence integrity:** if a WebAuthn approval credential bundle is embedded (or provided), the verifier can parse it and check it is internally consistent (credential id and public key match, SHA binding matches).

### What this spec does **not** claim

- It does **not** claim regulatory compliance.
- It does **not** claim that “hardware‑backed” is *always* true on every device.
- It does **not** claim that the browser verifier can evaluate the full attestation certificate chain or enterprise trust anchors.
- It does **not** claim MDM/enterprise policy enforcement unless your organization verifies it with your own attestation trust store.

**Important:** WebAuthn “attestation” is **evidence provided by the authenticator**. Trust evaluation is an organizational decision (e.g., allow‑list AAGUIDs, validate certificate chains, require enterprise attestation, etc.).

---

## 3) Artifact overview

### 3.1 Receipt countersignature (existing)

Countersigned receipts use:

- `mvg.receipt.countersigned@1`
- `mvg.receipt.countersignature@1`
- `mvg.receipt.countersign_payload@1`

### 3.2 WebAuthn assertion evidence (new)

When `signing_method: "webauthn"`, each countersignature additionally carries:

- `webauthn`: **assertion evidence** (`mvg.webauthn_assertion@1`)
  - `credential_id_b64u`
  - `authenticator_data_b64u`
  - `client_data_json_b64u`
  - `user_handle_b64u` (optional)

### 3.3 WebAuthn approval credential bundle (optional)

A reviewer can register a WebAuthn credential locally and export a bundle:

- `mvg.webauthn_approval_credential@1`

This bundle contains **no secrets**. It includes the credential’s public key and attestation object.

A countersignature may embed this bundle as `webauthn_credential`, or include only a digest reference:

- `payload.webauthn_credential_sha256: "sha256:<hex>"`

---

## 4) Canonical binding

### 4.1 Payload canonicalization

The countersign payload is canonicalized using MVG’s deterministic canonical JSON rules (sorted object keys; stable encoding).

### 4.2 Challenge derivation

The WebAuthn challenge is derived as:

- `challenge_bytes = SHA‑256( canonical_json(payload) )`
- `clientDataJSON.challenge` must equal `base64url(challenge_bytes)`

This makes the WebAuthn assertion **receipt‑bound** (no replay of an assertion to a different payload).

### 4.3 Signature verification input

WebAuthn signatures verify over:

- `signed = authenticatorData || SHA‑256(clientDataJSON)`

The verifier validates the signature using the embedded P‑256 public key (`payload.public_key_jwk`).

---

## 5) Attestation evidence handling

### 5.1 What the verifier can do in‑browser (offline)

The MVG verifier can:

- Parse the WebAuthn attestation object (CBOR) when present.
- Extract:
  - `fmt` (attestation format: `tpm`, `apple`, `android-key`, `packed`, `none`, …)
  - `AAGUID`
  - credential id + credential public key
- Check internal consistency against the exported bundle fields.

### 5.2 Trust evaluation (enterprise / legal)

Organizations may additionally:

- Validate attestation certificate chains against enterprise trust anchors.
- Require `attestation: "enterprise"` where supported.
- Enforce an allow‑list of AAGUIDs.
- Require specific authenticator attachment types (platform vs cross‑platform).

The public MVG verifier **does not** ship a vendor root store and does not claim that the attestation chain is trusted.

---

## 6) Minimal schema notes

### 6.1 `mvg.webauthn_approval_credential@1`

Required fields:

- `schema_id`
- `generated_utc`
- `rp_id`
- `origin`
- `credential_id_b64u`
- `public_key_jwk` (P‑256)
- `public_key_fingerprint_sha256`
- `attestation_object_b64u`
- `client_data_json_b64u`

Optional fields:

- `authenticator_attachment`
- `user_verification_policy`
- `attestation_conveyance`
- `attestation_summary`

### 6.2 `mvg.webauthn_assertion@1`

Required fields:

- `schema_id`
- `credential_id_b64u`
- `authenticator_data_b64u`
- `client_data_json_b64u`

Optional fields:

- `user_handle_b64u`

---

## 7) Operational recommendations

- Prefer `authenticatorAttachment: platform` for device‑bound approvals.
- Use `userVerification: required` for biometrics / PIN‑based approvals.
- If your environment supports it, consider `attestation: enterprise` and maintain an allow‑list of acceptable AAGUIDs.
- For auditability, embed `webauthn_credential` in the countersigned receipt **or** store it alongside the receipt and compare against `payload.webauthn_credential_sha256`.

---

## 8) Changelog

- **v1.0.0** — initial public release (WebAuthn receipt binding + optional attestation bundle).
