Skip to content

Getting Started

Paul White edited this page Aug 31, 2026 · 1 revision

Getting started

This walks through a first run: install Claviger, describe two identities, keep a tool authenticated through the gateway, and diff authorization between the two.

1. Install

Download a release binary from the releases page, or install with Go:

go install github.com/Su1ph3r/claviger@latest

Check it:

claviger version

2. Write a config

Save this as claviger.yaml. It describes the app under test and two identities: an admin and a low-privilege user, both logging in with a form POST.

target: https://app.example.com
identities:
  - name: admin
    type: form
    login_url: https://app.example.com/login
    username: admin
    password: "${ADMIN_PASSWORD}"
    logout:
      status_codes: [401]
  - name: user-a
    type: form
    login_url: https://app.example.com/login
    username: alice
    password: "${ALICE_PASSWORD}"
    logout:
      status_codes: [401]

Passwords come from the environment here (${VAR}); you can also use a literal password, a password_file, or a password_command. Set them:

export ADMIN_PASSWORD=... ALICE_PASSWORD=...

3. Start the daemon

claviger daemon --config claviger.yaml

It logs in each identity on demand, keeps the sessions warm, and prints a loopback gateway port per identity:

identity admin  -> http://127.0.0.1:8888
identity user-a -> http://127.0.0.1:8889
control socket: /run/user/1000/claviger.sock

In another terminal, watch session health live:

claviger watch

4. Drive a tool through the gateway

Point any HTTP tool at an identity's port instead of the real target. Claviger injects that identity's session and re-authenticates transparently when the token expires:

curl http://127.0.0.1:8889/api/records/42          # as user-a
ffuf -w paths.txt -u http://127.0.0.1:8888/FUZZ     # as admin, stays logged in

See Tool integrations for Burp, sqlmap, and nuclei.

5. Diff authorization

Send one request as several identities and compare the results:

claviger replay --as admin --as user-a --as anon --path /api/records/42
IDENTITY     STATUS SIZE     TIME
admin        200    412      1.2ms
user-a       403    21       0.9ms
anon         401    27       0.7ms

anon is a reserved name meaning "send no session". A low-privilege identity that returns a 200 where it should be blocked is the finding. To sweep many endpoints at once, feed a requests file, a HAR export, or an OpenAPI spec with --corpus; see the Authz diffing playbook.

Next steps

Clone this wiki locally