<!-- tempo-docs-context -->
> Source: [/docs/accounts/authentication/private-keys](https://tempo.xyz/developers/docs/accounts/authentication/private-keys.md)
> Section: [Accounts](https://tempo.xyz/developers/docs/accounts.md). Create accounts, set up signing methods, policies, access keys, key rotation, and fees, and follow guides for users, automations, agents, and teams.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# Private Keys

Signs for a Tempo account with a key you already hold in a wallet, KMS, or HSM.

<span id="what-a-private-key-is" />

## Overview

A private key is a secp256k1 or P-256 key that you hold. It lives in a wallet, a wallet provider, or your KMS or HSM. Tempo verifies each signature onchain. Use one for servers, scripts, treasury approvers, and backups. For a key that stays with the customer, use a [passkey](https://tempo.xyz/developers/docs/accounts/authentication/passkeys) or a [device key](https://tempo.xyz/developers/docs/accounts/authentication/device-keys) instead.

<span id="what-a-private-key-trusts" />

<span id="where-private-keys-live" />

<span id="recommended-roles-for-your-keys" />

<span id="private-key-sources" />

<span id="choose-a-role-for-each-key" />

<span id="roles" />

<span id="how-it-works" />

## Key Roles

Add each key as a signer or as an [access key](https://tempo.xyz/developers/docs/accounts/access-keys). A signer approves toward the account's [threshold](https://tempo.xyz/developers/docs/accounts/policies/signing-thresholds). An access key pays alone within its limits.

| Where the key lives | Add it as |
| --- | --- |
| CLI wallet, such as the [Tempo CLI wallet](https://tempo.xyz/developers/docs/cli/wallet) or Foundry `cast` | Access key for scripts and agents |
| Hardware, browser, or mobile wallet | Signer at weight 1, one per approver |
| [Wallet provider](https://tempo.xyz/developers/docs/accounts/apps/self-custodial-wallets), such as Turnkey or Privy | Signer at weight 1. The provider signs only when its own policies allow. |
| Cloud KMS or HSM | Signer for recovery, or access key for [backend payouts](https://tempo.xyz/developers/docs/accounts/automations/pay-out-from-a-backend) |

Anyone who can make the key sign approves at its weight, including anyone with signing access in your KMS. That lasts until you [remove the key](https://tempo.xyz/developers/docs/accounts/account-configuration/configuration-updates#remove-a-lost-or-compromised-signer).

<span id="require-two-treasury-signers" />

<span id="add-a-private-key-signer" />

## Add a Private Key

On mainnet and testnet today, a private key can be a single-key account's one key. That works like a standard Ethereum account. It can also be an access key on that account.

:::warning
**Multiple signers arrive with the [T14 network upgrade](https://tempo.xyz/developers/docs/protocol/upgrades/t14).** Until T14 activates, an account with several signers and a threshold runs only on the [Tempo Accounts devnet](https://tempo.xyz/developers/docs/accounts/create#connect-to-the-devnet), not on mainnet or testnet, and may still change.
:::

Signers need a configurable account, so this example runs only on the Tempo Accounts devnet. Give each key a weight below the threshold, so no single holder can pay alone. Keep each approver's key in its own wallet or HSM. Here both signers must approve.

```ts [treasury.ts]
import { Account } from 'viem/tempo'

const finance = Account.fromSecp256k1(process.env.FINANCE_SIGNER_KEY as `0x${string}`)
const operations = Account.fromSecp256k1(process.env.OPERATIONS_SIGNER_KEY as `0x${string}`)

const account = Account.fromConfig({ // [!code hl]
  // derive the address from these first signers
  address: 'infer', // [!code hl]
  // weight 1 each
  owners: [finance, operations], // [!code hl]
  threshold: 2, // [!code hl]
}) // [!code hl]
```

The example reads raw keys from the environment. To keep a key in its wallet, KMS, HSM, or provider, pass the Viem account that source provides. For a raw P-256 key, use `Account.fromP256`.

<span id="private-key-limits" />

## Limits

* A signer has no spending limit. To cap what a key can pay, make it an access key instead.
* Only the secp256k1 signers you create the account with could [recover funds sent to its address on another chain](https://tempo.xyz/developers/docs/accounts/account-configuration#recover-funds-sent-on-another-chain). No chain supports that recovery yet.

## Related

[Signing Thresholds](https://tempo.xyz/developers/docs/accounts/policies/signing-thresholds): Covers signer weights and the threshold a transaction must reach.

[Access Keys](https://tempo.xyz/developers/docs/accounts/access-keys): Covers keys that pay alone within limits, expiry, and scopes.

[Set Up a Team Multisig](https://tempo.xyz/developers/docs/accounts/custodians/team-multisig): Use for a treasury where any two of three approvers sign each payment.

[Configuration Updates](https://tempo.xyz/developers/docs/accounts/account-configuration/configuration-updates): Use for removing a lost or compromised signer.
