> ## Documentation Index
> Fetch the complete documentation index at: https://hevninc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Platform login is a web3 signature exchange for a JWT — and that JWT can never move money.

HEVN separates two completely different kinds of authorization:

|            | Platform authorization                                                  | Money authorization                                                                                                                 |
| ---------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Credential | HEVN JWT                                                                | Signature from a wallet owner key, or from an [API key](#api-keys-cli-rest-api-agents) within its onchain spend allowance           |
| Grants     | Contacts, invoices, contracts, bank details, KYC, statements, analytics | Transfers and any onchain state change                                                                                              |
| Issued by  | HEVN backend                                                            | The signer's own key, per operation                                                                                                 |
| If leaked  | Metadata exposure; **funds untouched**                                  | Owner key is never exposed (see [Privy](/general/privy-wallets)); a leaked API key is capped by its onchain allowance and revocable |

## Platform login flow

HEVN authenticates users the way web3 apps do — by proof of key ownership, not passwords:

<Steps>
  <Step title="Sign in with Privy">
    The user authenticates with their email or Google account, unlocking their [Privy embedded wallet](/general/privy-wallets) in the session.
  </Step>

  <Step title="Sign a login message">
    The app asks the Privy wallet to sign a challenge message. Signing a message is free, off-chain, and moves nothing.
  </Step>

  <Step title="HEVN verifies the signature">
    The backend recovers the signer address from the signature and checks it against the expected Privy address for that identity.
  </Step>

  <Step title="HEVN issues its own JWT">
    On success, HEVN issues a short-lived JWT scoped to platform features only.
  </Step>
</Steps>

There is no password database to breach and nothing HEVN stores that could be replayed to impersonate a wallet.

## What the JWT can and cannot do

The JWT authorizes the HEVN API surface: creating contacts, issuing and paying *requests* for invoices, generating contracts, requesting bank details, reading balances and statements.

<Warning>
  The JWT is **not** a spending credential. Even a fully compromised JWT cannot produce a wallet signature, and the wallet contract only accepts operations signed by an [onchain owner](/general/smart-wallets#ownership-verifiable-onchain). Money movement always terminates in a signature from an authorized key — the owner's, a teammate's, or an API key acting within its allowance.
</Warning>

## API keys (CLI, REST API, agents)

For automation, HEVN issues app-scoped `hvn_...` API keys (see [CLI authentication](/cli/overview#authentication-model) and [REST API authentication](/api-reference/authentication)). An API key is more than a bearer token — it is a **full EVM-compatible keypair**, and its spending ability is governed onchain, by the same standard as [teammate access](/general/shared-access):

1. **Platform scope.** The key is certified by HEVN for the platform API of one specific app: contacts, invoices, contracts, bank details, statements. This is the same trust level as the JWT.
2. **Spending scope — optional, granted onchain.** The key's EVM address can be granted a [Spend Permission](/general/shared-access#limited-access-spend-permissions) by the account owner, exactly like a human teammate with limited access. The owner signs a `SpendPermission` naming the key's address as `spender`, with an explicit allowance and period.

The consequences of this design:

* **Without a spend permission, an API key cannot move a single cent.** There is no backend code path that spends on the key's behalf; a transfer request is executed as a user operation signed by the API key itself, and the `SpendPermissionManager` contract accepts it only within the granted allowance.
* **A leaked key is capped and revocable.** The worst case is bounded by the remaining onchain allowance for the current period. The owner revokes the permission onchain (and the platform scope in the app) — after that, the key is inert.
* **The user's own key is never involved.** No key material leaves the [Privy layer](/general/privy-wallets); the API key is a separate identity with its own, strictly smaller, rights.

Every key's activity is fully observable in the app — spend against its allowance, transaction history, and its access footprint across payments, invoices, contracts, and cards:

<Frame caption="An AI agent operating on an API key: spend tracking, activity heatmap, and its access level — all bounded by the owner-granted permission">
  <img src="https://mintcdn.com/hevninc/LFQWsh1Hc0h_SGmj/images/agent-overview.png?fit=max&auto=format&n=LFQWsh1Hc0h_SGmj&q=85&s=038916f863675bd8b85d783cc8fee933" alt="Agent dashboard showing total spent, transactions, level of access, activity heatmap and access summary" width="2920" height="1930" data-path="images/agent-overview.png" />
</Frame>

Treat API keys as secrets: scope one per integration, grant the smallest allowance that works, store keys outside your codebase, and rotate them if exposed.
