v0.4.1 PRODUCTION ES256 / WebAuthn EUPL-1.2 LICENSED RFC INTERNET-DRAFT

The protocol that proves
a real human is here.

HHTTPS extends HTTP/HTTPS with cryptographic human verification. WebAuthn-backed, ES256-signed, GDPR-compliant, zero personal data stored. An open standard maintained by the HumanProof Initiative.

§ 1

Abstract

HHTTPS (Human-verified HTTPS) is an open protocol that adds a cryptographic proof-of-personhood layer on top of HTTPS. It allows web servers to verify that an HTTP request was initiated by a real human — without storing personally identifiable information.

The protocol combines three established standards: WebAuthn (W3C) for human presence verification, ES256-signed JWTs (RFC 7519) for portable claims, and JWKS (RFC 7517) for distributed verification. Adoption requires no central authority — any operator can run an HHTTPS issuer compatible with this spec.

Status
v0.4.1 — Production
Reference Implementation
hhttps.org
Algorithm
ES256 (P-256 / SHA-256)
License
EUPL-1.2 (open source)
§ 2

Design Principles

  • Zero PII storage. The issuer never stores name, address, or contact data. Only public keys, hashed identifiers, and ephemeral session state.
  • No central authority. Anyone can run an HHTTPS issuer. Tokens are verified against the issuer's public JWKS — no API key exchange, no rate-limited validation calls.
  • Standards over invention. WebAuthn, JWT, JWKS — all W3C/IETF standards. No proprietary cryptography. No new threat model.
  • European by default. GDPR-compliant by design. eIDAS-aware. Servers in the EU. No US cloud lock-in.
  • Roles, not identities. A token claims a role (e.g. medical_professional) and trust score (0–100), not a person.
  • Revocable. Tokens can be revoked via the issuer; revocation status is published in real-time at /hhttps/revoke/status.
§ 3

API Endpoints

All endpoints listed are part of the v0.4.1 reference implementation at hhttps.org. Custom prefixes are permitted; .well-known/hhttps-configuration is the source of truth for endpoint paths.

Discovery

GET
/.well-known/hhttps-configuration
Returns issuer metadata, supported roles, endpoint URLs.
GET
/.well-known/jwks.json
Returns the issuer's public keys (JWKS, RFC 7517).

WebAuthn Flow

POST
/hhttps/webauthn/register/start
Begin passkey registration; returns PublicKeyCredentialCreationOptions.
POST
/hhttps/webauthn/register/finish
Verify attestation; persist credential.
POST
/hhttps/webauthn/auth/{start,finish}
Authenticate with passkey, get verified session.
POST
/hhttps/role/declare
Declare role + verification method, receive access + refresh token.
POST
/hhttps/token/refresh
Exchange refresh token for fresh access token (no biometrics needed).

Token Operations

POST
/hhttps/check
★ The primary verification endpoint. Verify any HHTTPS token.
POST
/hhttps/validate
Validate token signature + revocation status only.
POST
/hhttps/revoke
Revoke a token (user-requested or compromised).
GET
/hhttps/revoke/status?jti=...
Public revocation lookup (no auth required).
§ 4

Token Format

An HHTTPS access token is a standard JWT (RFC 7519) signed with ES256. The payload contains claims about the verified human's role and trust level.

HHTTPS Token Payload (decoded)
{
  "jti":        "550e8400-e29b-41d4-a716-446655440000",
  // unique token identifier
  "iss":        "hhttps://hhttps.org",
  "sub":        "human-verified",
  "human":      true,
  "actorType":  "human",
  "role":       "medical_professional",
  "roleLevel":  "approbation-id",
  "trustScore": 93,
  "method":     "webauthn-passkey",
  "deviceType": "singleDevice",
  "ia":         1715242800,
  "exp":        1715246400
}

Tokens are short-lived (1 hour by default). Refresh tokens (7 days) allow extension without repeated WebAuthn challenges. Both can be revoked via /hhttps/revoke.

HTTP Headers

HHTTPS responses set the following headers, exposing verification status to client-side code and intermediaries:

Response Headers
HHTTPS-Protocol-Version: 0.4.1
HHTTPS-Status:           verified
HHTTPS-Human:            true
HHTTPS-Actor-Type:       human
HHTTPS-Role:             medical_professional
HHTTPS-Role-Level:       approbation-id
HHTTPS-Trust-Score:      93
HHTTPS-Method:           webauthn-passkey
HHTTPS-Issuer:           hhttps://hhttps.org
§ 5

Trust Scoring

Each verification method maps to a numeric trust score (0–100). Verifiers choose a minimum threshold based on their use case — a comment section may accept 30+, a medical-advice forum may require 90+.

self-declared
30
Baseline
webauthn
60
Passkey verified
email-verified
70
Domain-based
orcid
88
Researcher
approbation-id
93
Doctor / Pharmacist
notary-chamber
95
Notary
official-email
90
Civil servant
bundestag-id
98
Politician

See the full mapping in roles.js. Higher methods strictly imply lower ones (a score of 93 also satisfies any threshold ≤ 93).

§ 6

Integration

Verifying tokens requires no API call to the issuer — only the public JWKS, which can be cached for hours. Below: minimal Express middleware example.

Express middleware (Node.js)
import jwt        from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';

const jwks = jwksClient({
  jwksUri: 'https://hhttps.org/.well-known/jwks.json',
  cache: true, cacheMaxAge: 3600000
});

function requireHuman({ minTrust = 60, allowedRoles = null } = {}) {
  return async (req, res, next) => {
    const token = req.headers['hhttps-token'];
    if (!token) return res.status(401).json({ error: 'token required' });

    try {
      const decoded = await new Promise((resolve, reject) => {
        jwt.verify(token, getKey, { algorithms: ['ES256'] }, (e, d) => e ? reject(e) : resolve(d));
      });
      if (decoded.trustScore < minTrust)         throw new Error('trust too low');
      if (allowedRoles && !allowedRoles.includes(decoded.role)) throw new Error('role denied');
      req.hhttps = decoded;
      next();
    } catch (e) { res.status(401).json({ error: e.message }); }
  };
}

// Use it on any route:
app.post('/medical-advice',
  requireHuman({ minTrust: 90, allowedRoles: ['medical_professional'] }),
  postAdvice
);

Reference SDKs are available for JavaScript and Python, with examples for Express, Flask, Django, and FastAPI.

§ 6a

"Sign in with HHTTPS" button

Beyond JWT verification, HHTTPS provides a full OpenID Connect 1.0 flow. Your platform can offer a "Sign in with HHTTPS" button that lets users authenticate with their Passkey and bring along a verified role plus trust score — without sharing any PII with your platform.

Subjects are pairwise: each client sees a different stable identifier for the same user, so users cannot be tracked across platforms. PKCE is mandatory for public clients (no client secret required).

Step 1 — Redirect the user to HHTTPS
const verifier  = crypto.randomBytes(32).toString('base64url');
const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');
const state     = crypto.randomBytes(16).toString('base64url');
req.session.pkceVerifier = verifier;
req.session.oauthState   = state;

const params = new URLSearchParams({
  response_type:         'code',
  client_id:             'your-client-id',
  redirect_uri:          'https://your-site.com/auth/callback',
  scope:                 'openid role verification_method',
  state,
  code_challenge:        challenge,
  code_challenge_method: 'S256'
});

res.redirect(`https://hhttps.org/hhttps/oauth/authorize?${params}`);
Step 2 — Exchange code for token (on callback)
const tokenRes = await fetch('https://hhttps.org/hhttps/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type:    'authorization_code',
    code:          req.query.code,
    redirect_uri:  'https://your-site.com/auth/callback',
    client_id:     'your-client-id',
    code_verifier: req.session.pkceVerifier
  })
});

const { access_token, id_token } = await tokenRes.json();
// id_token is a JWT with: sub, role, role_label, trust_score,
// verification_method, nonce, exp, iat, iss, aud

Register your platform as an OAuth client by inserting a row into oauth_clients on the HHTTPS server (currently manual — public registration UI is on the roadmap). Discovery document at /.well-known/openid-configuration.

Real-world example: ask.iamhmn.org is a Q&A platform that uses this exact flow. Source code on GitHub.

§ 6b

Machine tokens — for bots and automated agents

HHTTPS recognizes that not all useful traffic comes from humans. Bots, AI agents, and automated services can register as machine operators and obtain tokens that carry a transparent actorType: 'bot' claim. Platforms can then treat machines and humans uniformly while keeping the difference visible to users.

In pilot mode, bots self-declare their role (no verification — no industry standard for AI agent identity yet exists). Role-based logic on the platform still applies, just as it does for human OAuth tokens.

Step 1 — Register your bot (once, store the API key)
curl -X POST https://hhttps.org/hhttps/machine/register \
  -H "Content-Type: application/json" \
  -d '{
    "operatorName":  "MyBot",
    "purpose":       "Answers technical questions on ask.iamhmn.org",
    "role":          "developer",
    "contactEmail":  "ops@example.com",
    "operatorUrl":   "https://example.com/bot"
  }'

# Response (save apiKey — shown only once):
# { "operatorId": "op-...", "apiKey": "mk-...", "role": "developer", ... }
Step 2 — Issue a token (each session)
curl -X POST https://hhttps.org/hhttps/machine/token \
  -H "Content-Type: application/json" \
  -d '{ "operatorId": "op-...", "apiKey": "mk-..." }'

# Returns: { "token": "eyJ...", "expiresAt": "..." }
# Token claims include: sub=machine, human=false, actorType=bot,
#                       operatorId, operatorName, purpose, role

Verify machine tokens the same way as human tokens — same JWKS, same ES256 signature. Distinguish them by the actorType claim. Token TTL is short (5 minutes by default) so bots refresh frequently — this gives the issuer the ability to revoke abusive operators quickly.

§ 7

Discovery

Any HHTTPS issuer publishes its configuration at /.well-known/hhttps-configuration. Clients use this to discover endpoints without hard-coding URLs:

GET /.well-known/hhttps-configuration
{
  "issuer":                   "hhttps://hhttps.org",
  "protocol_version":         "0.4.1",
  "jwks_uri":                "https://hhttps.org/.well-known/jwks.json",
  "check_endpoint":          "https://hhttps.org/hhttps/check",
  "registration_endpoint":   "https://hhttps.org/hhttps/webauthn/register/start",
  "authentication_endpoint": "https://hhttps.org/hhttps/webauthn/auth/start",
  "revocation_endpoint":     "https://hhttps.org/hhttps/revoke",
  "supported_algorithms":    ["ES256"],
  "supported_roles":         ["citizen", "journalist", ..., "craftsman"],
  "token_ttl":                3600,
  "refresh_ttl":              604800
}
§ 8

Security Considerations

  • Private keys never leave the user's device. WebAuthn enforces this in hardware (TPM, Secure Enclave, YubiKey).
  • Issuer signing keys must be rotated periodically. JWKS supports multi-key publishing for seamless rotation.
  • The token's jti is logged at issuance and removed at expiration. Revocation persists permanently.
  • Replay protection: each WebAuthn ceremony uses a fresh server-generated challenge.
  • The RP_ID binds passkeys to a specific origin. A token issued at hhttps.org cannot be authenticated against a different origin.
  • Rate-limiting is applied per IP at all sensitive endpoints (registration, authentication, email, revocation).
  • For maximum trust, issuers SHOULD publish a transparency log of issued/revoked token hashes (planned for v0.5).
§ 9

Governance & License

The HHTTPS specification and reference implementation are released under the European Union Public Licence (EUPL-1.2) — an OSI-approved license compatible with GPLv3, AGPLv3, MPLv2, and most permissive licenses, with explicit GDPR alignment.

The protocol is maintained by the HumanProof Initiative (github.com/dhannus/HumanProof), an unfunded civic-tech project. Anyone may propose changes via pull request. Major specification revisions require public discussion period (≥ 30 days).

An IETF Internet-Draft is in preparation. Once stable, the protocol will be submitted for standardization through the IETF process — independent of the reference implementation.

Initiative contact: daniel.hannuschka@tweakz.de · Press & institutional inquiries welcome.