Skip to main content
Version: v4.0.0-nightly.20260210

Using Authentication Witnesses

This guide shows you how to create and use authentication witnesses (authwits) to authorize other accounts to perform actions on your behalf.

aztec-nr

Using AuthWitnesses is always a two-part process. This guide shows how to generate and use them, but you still need to set up your contract to accept and authenticate them.

Therefore it is recommended to read the aztec-nr guide on authwitnesses before this one.

Prerequisites

Intent types

The authwit system supports different intent types depending on your use case:

  • CallIntent: Use when authorizing a specific contract function call. Contains { caller, action } where action is a ContractFunctionInteraction.
  • IntentInnerHash: Use when authorizing arbitrary data. Contains { consumer, innerHash } where consumer is the contract that will verify the authwit.

Create private authwits

Private authwits authorize actions in the private domain. The authorization is included directly in the transaction that uses it.

Let's say Alice wants to allow Bob to transfer tokens from her account. Alice is the authorizer (she owns the tokens) and Bob is the caller (he will execute the transfer):

private_authwit
// Alice wants to allow Bob to transfer tokens from her account (private)
const privateNonce = Fr.random();

// Define the action Bob will execute
const privateAction = tokenContract.methods.transfer_in_private(
aliceAddress, // from
bobAddress, // to
100n, // amount
privateNonce, // authwit nonce for replay protection
);

// Alice creates an authwit authorizing Bob to call this function
const privateWitness = await wallet.createAuthWit(aliceAddress, {
caller: bobAddress,
action: privateAction,
});

// Bob executes the transfer, providing the authwit
await privateAction.send({ from: bobAddress, authWitnesses: [privateWitness] });
Source code: docs/examples/ts/aztecjs_authwit/index.ts#L34-L54
tip

The nonce prevents replay attacks. When from and msg_sender are the same (self-transfer), set the nonce to 0.

Create public authwits

Public authwits require a transaction to store the authorization in the AuthRegistry contract before the authorized action can be executed:

public_authwit
// Alice wants to allow Bob to transfer tokens from her account (public)
const publicNonce = Fr.random();

// Define the action Bob will execute
const publicAction = tokenContract.methods.transfer_in_public(
aliceAddress, // from
bobAddress, // to
100n, // amount
publicNonce, // authwit nonce
);

// Alice sets the public authwit (this requires a transaction)
const authwit = await wallet.setPublicAuthWit(
aliceAddress,
{ caller: bobAddress, action: publicAction },
true, // authorized
);
await authwit.send();

// Now Bob can execute the transfer
await publicAction.send({ from: bobAddress });
Source code: docs/examples/ts/aztecjs_authwit/index.ts#L56-L78

Create arbitrary message authwits

Use this when authorizing arbitrary data rather than a specific contract function call:

arbitrary_authwit
import { computeInnerAuthWitHash } from "@aztec/aztec.js/authorization";

// Create hash of arbitrary data
const innerHash = await computeInnerAuthWitHash([
Fr.fromHexString("0xcafe"),
Fr.fromHexString("0xbeef"),
]);

// Create an intent with the consumer contract address
const intent = {
consumer: tokenContract.address,
innerHash,
};

// Create the authwit for arbitrary data
const arbitraryWitness = await wallet.createAuthWit(aliceAddress, intent);
console.log("Arbitrary authwit created:", arbitraryWitness);
Source code: docs/examples/ts/aztecjs_authwit/index.ts#L80-L98

The consumer is the contract address that will verify this authwit.

Revoke public authwits

Public authwits can be revoked by setting authorized to false:

revoke_authwit
// Revoke a public authwit by setting authorized to false
const revokeNonce = Fr.random();
const revokeAction = tokenContract.methods.transfer_in_public(
aliceAddress,
bobAddress,
50n,
revokeNonce,
);

// First, set the authwit
const setAuthwit = await wallet.setPublicAuthWit(
aliceAddress,
{ caller: bobAddress, action: revokeAction },
true,
);
await setAuthwit.send();

// Later, revoke it
const revokeInteraction = await wallet.setPublicAuthWit(
aliceAddress,
{ caller: bobAddress, action: revokeAction },
false, // revoke authorization
);
await revokeInteraction.send();
Source code: docs/examples/ts/aztecjs_authwit/index.ts#L100-L125

Next steps