Skip to content

Latest commit

 

History

History
111 lines (91 loc) · 3.6 KB

File metadata and controls

111 lines (91 loc) · 3.6 KB

Agentcha Architecture

Agentcha is split into a browser widget and a server verifier. The browser renders challenges and records interaction telemetry. The server owns trust decisions.

Components

flowchart TB
    subgraph Client
        Page["Protected page"]
        Widget["@agentcha/widget"]
        Badge["Protected by Agentcha badge"]
    end

    subgraph Server
        Verify["Verifier endpoint"]
        Store["Challenge store"]
        Signer["Token signer"]
        Content["Protected content endpoint"]
    end

    Page --> Widget
    Widget --> Badge
    Widget --> Verify
    Verify --> Store
    Verify --> Signer
    Page --> Content
    Content --> Signer
Loading

Verification Flow

sequenceDiagram
    participant B as Browser or agent
    participant W as Widget
    participant V as Verifier
    participant S as Challenge store
    participant C as Content endpoint

    B->>W: Page interaction
    W->>V: Challenge request with site key and action
    V->>S: Store expected answer and timing
    V-->>W: Public challenge
    B->>W: Typed answer
    W->>V: Submit answer and telemetry
    V->>S: Consume challenge
    alt First correct answer
        V-->>W: Next challenge in chain
    else Second correct answer
        V-->>W: Signed token
        W->>C: Request content with token
        C->>V: Verify token scope
        C-->>W: Protected content
    else Wrong or replayed answer
        V-->>W: Fresh challenge and reset chain
    end
Loading

Trust Boundaries

flowchart LR
    DOM["DOM state"]:::weak -->|not trusted| Server["Server decision"]
    LocalStorage["localStorage"]:::weak -->|not trusted| Server
    Event["verified event"]:::weak -->|notification only| Server
    Token["Signed token"]:::strong -->|verified server-side| Server
    Store["One-time challenge state"]:::strong --> Server

    classDef weak fill:#fff7ed,stroke:#c2410c,color:#111827
    classDef strong fill:#ecfdf5,stroke:#047857,color:#111827
Loading

The widget can improve UX and raise the cost of casual bypass, but it cannot make browser-side data private. Protected content must be fetched from a server endpoint after token verification.

Challenge Lifecycle

  1. The verifier creates a challenge with a server-held expected answer.
  2. The public challenge omits the expected answer and any hidden answer field.
  3. The client waits until the answer readiness window.
  4. The verifier consumes the challenge on answer submission.
  5. A wrong answer, replay, expired challenge, or spray attempt resets the chain.
  6. Two consecutive correct challenges issue a signed token.
  7. The content endpoint verifies the token and consumes the token ID where practical.

Package Layout

packages/widget
  src/agentcha-widget.ts    Web Component, modal, badge, telemetry
  src/telemetry.ts          Browser interaction signal collection

packages/verify
  src/handler.ts            Request handler, chain state, token flow
  src/challenge.ts          Challenge generation
  src/token.ts              Signed token creation and verification
  src/webBotAuth.ts         Web Bot Auth helper logic
  templates/                Edge and serverless examples

apps/demo
  src/pages/agentcha.astro  Demo protected route
  src/pages/api/agentcha    Verify and content endpoints

Operational Notes

  • Use a durable challenge store when traffic can hit more than one server instance.
  • Keep AGENTCHA_SECRET server-only.
  • Rate-limit challenge issuance and answer submission per session and IP.
  • Log challenge type, result, timing, and reset reason.
  • Treat Web Bot Auth as additive identity signal, not a replacement for challenge verification.