# Account Abstraction on EVMs Source: https://docs.dfns.co/advanced/account-abstraction-on-evms Use account abstraction (ERC-4337) with DFNS MPC wallets to enable smart contract wallet features like gas sponsorship and batched transactions on EVM chains. The following article is relevant primarily for EVM compatible networks. ## Overview Ethereum and other Ethereum virtual machine (EVM) compatible networks require transactions to be originated from an externally owned account (EOA) and for that account to pay the gas fees for the transaction in the native cryptocurrency of the chain (for example, Ether in the case of Ethereum). Blockchain users pay gas in order to purchase scarce block space and fund the chain, incentivizing validators to participate in securing the network. For projects operating primarily over tokens or NFTs, however, requiring a native cryptocurrency balance to fund transactions introduces onboarding friction. Additionally, ensuring end-user wallets are sufficiently funded to execute transactions creates ongoing operational overhead. For these reasons, the notion of β€œgasless” or "sponsored" transactions has been an area of ongoing debate for a number of years. Unfortunately, the Ethereum community has failed to settle on a single standard nor enshrined this capability in the layer 1 protocol, leaving developers to contend with various approaches and weigh trade-offs depending on their specific use case. Various approaches to achieving sponsored transactions are outlined below. ## Account Abstraction (ERC-4337) One of the newest approaches to enabling sponsored transactions on EVM chains is to use paymasters as specified in [ERC-4337](https://www.erc4337.io/), Account Abstraction (AA). AA separates (or abstracts) authentication against smart contract wallets from the requirements of the underlying protocol (specifically ECDSA/secp256k1 signatures). Additionally, it specifies standards for executing sponsored transactions using smart contracts called paymasters. Transactions in AA are encapsulated in a higher level format called user operations and submitted to an off chain network of bundlers which batch and send them to the chain through a singleton entry point contract. Every user operation must be signed before it can be submitted to the chain. Increasingly, DFNS customers are relying on our advanced MPC solution to ensure secure and highly available signing of user operations. The DFNS engineering team has built proofs of concept (POCs) to demonstrate how to integrate our MPC signing with various partners offering AA platforms. ### Biconomy Biconomy is a web3 infrastructure provider offering a full stack solution for AA. You can read about their solution [here](https://www.biconomy.io/smart-accounts). DFNS has built a sample integration which processes a gasless transaction on the Mumbai testnet. You can find a Readme and the full code [here](https://github.com/dfns/dfns-sdk-ts/tree/m/examples/libs/viem/biconomy-aa-gasless). ### Safe In addition to being the industry-leading Smart Account, Safe also supports ERC-4337 via Modules and the FallbackHandler with a flow documented [here](https://docs.safe.global/home/4337-safe). The [Safe4337Module](https://github.com/safe-global/safe-modules/blob/main/modules/4337/contracts/Safe4337Module.sol) extends the Safe Smart Account to enable ERC-4337 compliant transactions, received via the proxy contract. This functionality is exposed via the Relay Kit in the Safe SDK - check [this guide](https://docs.safe.global/home/4337-guides/safe-sdk) on how to integrate it. To use DFNS with Safe AA, simply use our [Generate Signature API](/api-reference/keys/generate-signature) to sign User Operations sent through your bundler to the Safe proxy. ### ZeroDev ZeroDev is a 4337 provider offering Bundler and Paymaster services as described in [their docs](https://docs.zerodev.app/). DFNS has built a sample integration demonstrating a sponsored transaction using our viem wrapper which is available [here](https://github.com/dfns/dfns-sdk-ts/tree/m/examples/libs/viem/zerodev-aa-gasless). Follow [their quickstart](https://docs.zerodev.app/sdk/getting-started/quickstart) to begin an integration. ## Meta-Transactions (ERC-2771) Meta-transactions are an earlier attempt to enable sponsored transactions as specified in [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771). In this approach, end user transactions are forwarded off-chain to relayers that fund gas cost in exchange for a fee. The primary caveat is the target contract must support the standard by implementing the [ERC2771Context](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol) interface which replaces the built in msg.sender variable with a \_MsgSender() function. This implementation extracts the original sender from the call data to prevent the relayer address from being used in its place. If you control the target smart contact and can support this interface or if you have validated your target contract already supports 2771, there are a number of relayer providers you can work with in order to sponsor transactions on behalf of your users and provide a gasless user experience while signing transactions with DFNS. The following are a few examples. ### Open Gas Station Network (GSN) GSN is an open-source public good funded by the Ethereum Foundation and built by the authors of ERC-2771 to help promote the standard. They offer detailed [documentation](https://docs.opengsn.org/) on configuring a relayer and have published a sample ["capture the flag" workshop](https://github.com/opengsn/workshop) to demonstrate the changes required to make a smart contract compatible with 2771. They even have a [detailed tutorial on setting up a relay server](https://docs.opengsn.org/relay-server/tutorial.html#introduction). You can reach out to the GSN team in [discord](https://discord.gg/NXXTCbh58s) with any questions. ### Biconomy Biconomy is one of the longest standing players in the relayer market. They offer [meta-transaction support](https://docs.biconomy.io/) to enable sponsored transactions using the ERC-2771 standard. Their documentation covers implementing gasless transactions and enabling smart contracts for 2771 support. Feel free to reach out to the Biconomy team through their [documentation site](https://docs.biconomy.io/) with any questions specific to their offering. ### Gelato Network Gelato describes themselves as "web3’s decentralized backend" and provides a number of services to enhance smart contracts, including 2771 compatible relayers. They expose a centralized funding service called [1 Balance](https://docs.gelato.network/developer-services/1balance). Once an account is funded, it can be used to sponsor transactions on behalf of users by implementing [sponsoredCallERC2771](https://docs.gelato.network/developer-services/relay/erc-2771-recommended/sponsoredcallerc2771) as detailed in their documentation. Please contact Gelato directly with questions pertaining to their specific configuration. ## Automated "Gas Tanks" The final approach to enabling gasless transactions is simply to transfer the required amount of the native cryptocurrency into each end users' wallet, relieving them from the responsibility of acquiring it themselves. In most cases, implementations of this approach specify a "gas tank" wallet which automatically sends cryptocurrency to other wallets when they fall below a given threshold. The primary problem with this approach is the cost of sending each individual "refuel" transaction on chain. Looking at the economics on the Ethereum L1, it does not scale well as demonstrated in the calculations below: ## Next Steps Check out how DFNS has implemented [Fee Sponsorship](/features/fee-sponsors)! If you're interested in implementing sponsored transactions or have a novel approach to the problem, don't hesitate to reach out to us as this is one of our favorite topics of discussion. As always, feel free to reach out to our Support Team. # Delegated wallets Source: https://docs.dfns.co/advanced/delegated-wallets Give end users full ownership of their non-custodial wallets while you provide the infrastructure, with passkey authentication and policy controls. ## What is a delegated wallet? A delegated wallet is a wallet where **your end user has full control**, not your company. Think of it like giving someone the only key to a safe deposit box: you provide the box, but only they can open it. When you delegate a wallet: * Only your user can move funds or sign transactions * Your company cannot access the wallet's assets * Your user proves ownership using biometrics (Face ID, fingerprint) or a security key Ready to implement? See the [end-user wallets solution](/solutions/embed-user-wallets) for a step-by-step implementation overview. ## Why delegate wallets? ### Clear signing authority With delegated wallets, only the end user holds the credentials (passkey) required to sign transactions. Your organization cannot authorize transactions on their behalf, giving users verifiable proof that they alone control their wallet. ### User trust Users have cryptographic proof that only they can use their wallet. Your company physically cannot move their assets without the user's explicit approval via their passkey. ### Reduced liability Since you cannot authorize transactions from delegated wallets, you reduce your exposure to internal threats targeting user assets. ## How it works ### Architecture DFNS uses distributed key generation and threshold signatures to secure wallets. Private key shares are encrypted and stored across a decentralized signer network spread across multiple data centers and geographic regions. The wallet private keys never leave DFNS infrastructure. They are not stored on the user's device. ```mermaid theme={null} flowchart LR subgraph user["User's Device"] passkey["πŸ” Passkey"] end subgraph your["Your Infrastructure"] app["Your App"] end subgraph dfns["DFNS"] api["API"] signers["Distributed Signers"] end passkey -->|"Signs request"| app app -->|"Authenticated request"| api api -->|"Coordinates signing"| signers ``` The key insight is that **the signing credential determines who can use the wallet**. Authorizing a transaction requires both an access token and a signing credential (passkey). In a delegated configuration, the signing credential lives on your user's device, so only they can authorize transactions. DFNS is a technical infrastructure provider. Regardless of the wallet model, DFNS secures the cryptographic key material in its MPC network. The difference between org-managed and delegated wallets is **who holds the signing authority**: your organization's credentials, or your end user's passkey. "Custody" is a legal term with jurisdiction-specific meaning; consult legal counsel for your specific regulatory situation. This is different from traditional wallet solutions like MetaMask or Ledger, where users must secure a seed phrase. With DFNS delegated wallets: * Users authenticate with familiar biometrics instead of seed phrases * If a credential is compromised, it can be revoked * If a credential is lost, it can be recovered ### Transaction flow 1. **User signs up** - They register with your app and set up a passkey (biometric or security key) 2. **Wallet is created** - Your system creates a wallet and delegates it to the user 3. **User transacts** - When they want to send funds, they approve with their biometric 4. **You can't intervene** - Your company has no ability to approve or block their transactions ## User experience From your user's perspective, delegated wallets feel like any modern app: * Sign up with email or social login * Approve transactions with Face ID or fingerprint * No seed phrases to write down or remember * Can recover access if they lose their device ## Recovery Delegated wallets can be recovered, but only if you build the recovery flow. If a user loses their only passkey and you never registered a recovery credential or prompted them to add a second device, the wallet is permanently inaccessible. DFNS cannot restore it. | | Seed phrase wallet | Delegated wallet (DFNS) | | -------------------- | ------------------- | -------------------------------------------------- | | If credential lost | Funds lost forever | Recoverable if you built recovery, otherwise lost | | If credential stolen | Funds stolen | Credential can be revoked | | Backup method | Write down 24 words | Register a second passkey or a recovery credential | You have three mechanisms to offer your users. Register a recovery credential at signup, prompt for a second device shortly after, and treat the recovery flow as a required part of your implementation, not a polish step. See [Implement end-user recovery](/guides/developers/end-user-recovery) for code examples. ## Trade-offs | Delegated wallets | Organization-managed wallets | | ---------------------------------------- | ----------------------------------------- | | End user holds signing authority | Your organization holds signing authority | | No spending limits or approval workflows | Policies can restrict transactions | | User responsible for recovery | You can help users recover access | | Only the user can authorize transactions | Your team authorizes transactions | ## When to use delegated wallets **Good fit:** * Consumer apps where users expect to control their assets * Regulatory environments where signing authority matters * Products where user trust and transparency matter **Consider org-managed instead:** * Treasury or operational wallets * Scenarios requiring spending limits or multi-approval * When users expect you to help if something goes wrong ## White-labeling Delegation allows you to provide DFNS wallet infrastructure without exposing DFNS to your users. Your backend registers and logs in users to DFNS on their behalf. Users only interact with your app and your brand: no DFNS emails, no DFNS branding. When users need to sign transactions, your app prompts them for their passkey directly. End users are first-class citizens in DFNS. Once registered, they could use the DFNS APIs directly if they access their auth token. Carefully review your policies and controls. ## Learn more * [End-user wallets solution](/solutions/embed-user-wallets) - Implementation overview * [Implementing delegated wallets](/guides/developers/delegated-wallets) - Step-by-step developer guide * [End-user recovery](/guides/developers/end-user-recovery) - Implementing recovery # Disaster recovery Source: https://docs.dfns.co/advanced/deployment-models/disaster-recovery Backup and recovery options across all DFNS deployment models, including signer failover, Layer 4 independent recovery, and manual key backup via key export. Backup and disaster recovery responsibilities depend on your [deployment model](/advanced/deployment-models). With fully-managed DFNS Cloud (SaaS), DFNS operates the signers and handles all backup and disaster recovery for you. With hybrid or on-premise deployments, you operate one or more signers yourself and are responsible for backing up and recovering the components in your environment. This page covers what to protect and how to recover in each case. Beyond restoring infrastructure, two customer-controlled options give MPC wallets an independent recovery path, so you can reconstruct your keys and keep operating even if DFNS is unavailable. Both back up the same thing β€” each signer's key share, encrypted to a key only you hold β€” and differ only in how the backup is triggered: * **[Manual key backup](#manual-key-backup-key-export)** β€” export a wallet's key shares on demand, and reconstitute the full key locally only when you need it. Available to most customers. * **[Layer 4](#layer-4-disaster-recovery)** β€” the same backup, made automatically and continuously to storage you own. Dedicated MPC clusters only. ## MPC signer backups When hosting MPC signers, the following assets must be backed up: | Asset | Impact of loss | Backup approach | | -------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | | **Encryption keys** | All encrypted key shares become permanently unusable. Loss means loss of all wallets and assets. | Store in a secrets manager with backup/replication enabled. | | **Key share databases** | Loss of a database means losing that signer's key shares created since the last backup. | Standard database backup procedures (pg\_dump, continuous archiving, replicas). | | **mTLS certificates and private keys** | Required for signer authentication to DFNS APIs and delivery server. | Store in a vault or secrets manager. | | **Signer configuration** | Needed to redeploy signers. | Store in version control or a configuration management system. | ### Recovery scenarios | Scenario | Recovery | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Single signer failure** | Deploy a replacement signer, restore its configuration, certificates, and database access. If the threshold is still met by remaining signers, signing continues uninterrupted during recovery. | | **Database loss** | Restore from backup. Key shares created after the last backup are lost. With [Layer 4](#layer-4-disaster-recovery), you can recover them independently from your own backups. | | **Encryption key loss** | **Unrecoverable** without Layer 4. All key shares encrypted with those keys are permanently inaccessible. With [Layer 4](#layer-4-disaster-recovery), you can recover independently. | | **Multiple signer failures (below threshold)** | Signing is unavailable until enough signers are restored to meet the threshold. | Losing your encryption keys without Layer 4 means losing access to all wallets and the assets they hold. ## HSM backups When using an HSM integration, the following assets must be backed up: | Asset | Impact of loss | Backup approach | | -------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | **HSM master key** | All wrapped keys become permanently unusable. Loss means loss of all wallets and assets. | Use your HSM vendor's key backup mechanism (e.g. Thales Luna Backup HSM, cloning domain). Store backups in a physically separate, secure location. | | **Wrapped-key database** | Loss means losing all wallets and assets created since the last backup. | Standard database backup procedures (pg\_dump, continuous archiving, replicas). Data is encrypted at rest but should still be treated as sensitive. | | **mTLS certificates and private keys** | Required for HSM Driver authentication to DFNS APIs. | Store in a vault or secrets manager. The intermediate certificate private key is especially critical. | | **HSM Driver configuration** | Needed to redeploy the Driver. | Store in version control or a configuration management system. | ### Recovery scenarios | Scenario | Recovery | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | **HSM Driver host failure** | Deploy a new host, install the HSM client library and HSM Driver, restore configuration and mTLS certificates. The Driver resumes polling automatically. | | **HSM failure** | Provision a replacement HSM with the same master key (restored from backup). The HSM Driver resumes without further changes. | | **Database loss** | Restore from backup. Wallets created after the last backup, and the assets they hold, are lost. | | **Master key loss** | **Unrecoverable.** All wallet keys encrypted with that master key are permanently inaccessible. | Losing the HSM master key means losing access to all wallets and the assets they hold. Back it up immediately after generation. ## Layer 4 disaster recovery Layer 4 gives dedicated MPC clusters a fully independent recovery path. It automatically encrypts each key share with your Ed25519 public key during wallet creation and stores the encrypted backup in an S3 bucket you own. Layer 4 requires a dedicated MPC cluster; it is not available on the standard shared DFNS Cloud infrastructure that most customers use. Once you have a dedicated cluster, Layer 4 works with any [MPC deployment option](/advanced/deployment-models/mpc): fully managed by DFNS, hybrid, or on-premise. Without a dedicated cluster, use [manual key backup](#manual-key-backup-key-export) instead β€” as most customers do. ### How it works When Layer 4 is enabled, each signer encrypts its key share with your public key every time a key is generated, imported, or copied. The encrypted share is then written to your S3 bucket. DFNS never has access to your private key, so only you can decrypt and recover the backups. ```mermaid theme={null} sequenceDiagram participant App as Your application participant API as DFNS API participant S as Signer participant DB as Signer database participant S3 as Your S3 bucket App->>API: Create wallet API->>S: DKG request S->>S: Generate key share (MPC) S->>DB: Store encrypted key share S->>S3: Encrypt share with your public key, store S-->>API: Public key API-->>App: Wallet created ``` Each signer writes to its own prefix in the bucket (e.g. `signer-0/`, `signer-1/`). The backup happens automatically for every wallet created after Layer 4 is enabled. ### What Layer 4 protects against * **Encryption key loss**: Without Layer 4, losing signer encryption keys is unrecoverable. With Layer 4, you can decrypt key shares from your own storage. * **Database loss beyond last backup**: Standard database backups have a recovery point. Layer 4 backups are written at key generation time, so no gap exists. * **DFNS unavailability**: Recovery is entirely independent of DFNS. You only need your private key and the backup files. ### Security properties * **Customer-controlled encryption.** Shares are encrypted with your Ed25519 public key. DFNS cannot decrypt the backups. * **Write-only signer access.** Signers have `s3:PutObject` permission only. They cannot read, modify, or delete existing backups. * **Independent recovery.** You can recover your keys at any time using only your private key and the backup files. * **Complementary to database backups.** Layer 4 does not replace standard database backups. It provides an additional recovery path for scenarios where those backups are unavailable. ### Setup Layer 4 setup is covered in the MPC signer deployment. It involves generating an Ed25519 key pair, creating an S3 bucket, and configuring the signers. To enable Layer 4 or for questions about the setup process, contact our Support Team. ## Manual key backup (key export) You can export a copy of any MPC wallet's key on demand, giving you a backup you hold outside DFNS. It is the fallback available to most customers, whatever their deployment model. As with Layer 4, DFNS never handles a plaintext key ([how export works](/advanced/key-import-and-export#export)). A reconstituted key is a full, standalone private key β€” a single point of failure. Anyone who obtains it controls the wallet and its assets, and DFNS cannot guarantee the security of transactions signed with it. Once it leaves DFNS, its security is entirely your responsibility: storage, encryption at rest and in transit, access controls, usage restrictions, and protection against theft or misuse. Manual export is a point-in-time backup: you can only recover keys you exported before a loss. To have every key covered automatically, use Layer 4. Treat exported material as break-glass: store the encrypted shares β€” and any reconstituted key β€” offline with tightly restricted access. For the step-by-step export and recovery procedure, including an offline signing test, see the [export keys guide](/guides/developers/export-keys). ### Layer 4 vs. manual key backup Both produce the same artifact: each signer's key share, encrypted to a key you control, and both recover through the same client-side reconstitution. DFNS never holds a plaintext key in either case. They differ only in how and when the backup is made: | | Layer 4 | Manual key export | | ---------------- | ---------------------------------- | ---------------------------------------------- | | **Trigger** | Automatic, at every key generation | On demand, via the Export Key API | | **Coverage** | Every key, continuously | Only the keys you export, at export time | | **Storage** | Written to an S3 bucket you own | Returned to your client to store as you choose | | **Availability** | Dedicated MPC clusters | Any MPC deployment | # HSM signing infrastructure Source: https://docs.dfns.co/advanced/deployment-models/hsm How DFNS integrates Hardware Security Modules as an alternative to MPC for securing wallet keys in regulated and enterprise environments. DFNS supports Hardware Security Modules (HSMs) as an alternative to [MPC](/advanced/deployment-models/mpc) for securing wallet keys. By leveraging an HSM, your cryptographic keys are generated and protected within tamper-resistant hardware that you own and operate. The HSM integration is seamless: all DFNS APIs, SDKs, policies, and features work identically regardless of the underlying key storage. Once the HSM is deployed, no changes are required to your integration. HSM on-premise architecture ## Architecture The HSM deployment consists of four components running in your infrastructure: | Component | Description | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **HSM** | A Hardware Security Module that you procure and manage. It performs cryptographic operations and protects the master key. See [supported HSMs](#supported-hsms). | | **Host server** | The machine running the HSM Driver and database. It must have network connectivity to both the internet (to reach DFNS APIs) and the HSM. | | **HSM Driver** | Software provided by DFNS that bridges the DFNS API and the HSM. It polls the API for key generation and signing requests, and translates them into PKCS#11 commands. | | **Database** | Stores wrapped (encrypted) keys. Private keys are not stored inside the HSM. The HSM only holds the master key used to wrap and unwrap them, so key storage capacity is not limited by the HSM. | You are responsible for procuring, provisioning, and operating all of these components. DFNS provides the HSM Driver software and coordinates mTLS certificate setup, but does not have access to your infrastructure or keys. DFNS does not participate in the administration or management of your HSM. All HSM-related operations, including provisioning, configuration, and master key management, are handled exclusively by you. This ensures that DFNS personnel have no access to the cryptographic keys. ## Supported HSMs DFNS ships fully validated integrations for the following HSMs. Signature scheme support varies by model: | HSM | ECDSA | EdDSA (Ed25519) | | ------------------------------------------- | ----- | --------------- | | Thales Luna (Network, PCIe, Luna Cloud HSM) | βœ… | βœ… | | Securosys Primus (including CloudHSM) | βœ… | βœ… | | IBM HPCS / EP11 | βœ… | βœ… | | AWS CloudHSM | βœ… | ❌ | Note that EdDSA requires the HSM to run in non-FIPS mode. Without EdDSA support, wallets on Ed25519-based networks (such as Solana or Stellar) cannot be created: AWS CloudHSM is limited to ECDSA-based networks such as EVM chains. Need to validate a different PKCS#11-compatible HSM: contact our Support Team to confirm support for your model. ## HSM usage DFNS employs a stateless approach to HSM usage. Private keys are never stored persistently inside the HSM. Instead, they are wrapped (encrypted) by the HSM's master key and stored in the database. The HSM unwraps them in-memory only when needed for cryptographic operations. This design simplifies integration, enhances disaster recovery, and ensures compatibility with a broad range of HSMs. ### Key generation ```mermaid theme={null} sequenceDiagram participant App as Your application participant API as DFNS API participant Driver as HSM Driver participant HSM participant DB as Database App->>API: Create wallet or key Driver->>API: Poll for requests (mTLS) API-->>Driver: Key generation request Driver->>HSM: Generate key pair (PKCS#35;11) HSM-->>HSM: Generate key pair & wrap private key with master key HSM-->>Driver: Wrapped private key + public key Driver->>DB: Store wrapped key Driver->>API: Return public key API-->>App: Wallet created ``` 1. Your application requests a new wallet through the DFNS API. 2. The HSM Driver polls the DFNS API over mTLS and picks up the key generation request. 3. The Driver forwards the request to the HSM via PKCS#11. 4. The HSM generates a new key pair, wraps the private key with its master key, and returns the wrapped key. 5. The Driver stores the wrapped key in the database and returns the public key to your application. ### Transaction signing ```mermaid theme={null} sequenceDiagram participant App as Your application participant API as DFNS API participant Driver as HSM Driver participant HSM participant DB as Database App->>API: Sign transaction Driver->>API: Poll for requests (mTLS) API-->>Driver: Signing request + payload Driver->>DB: Retrieve wrapped key DB-->>Driver: Wrapped key Driver->>HSM: Wrapped key + payload (PKCS#35;11) HSM-->>HSM: Unwrap key & sign payload HSM-->>Driver: Signature Driver->>API: Return signature API-->>App: Transaction signed ``` 1. Your application submits a transaction through the DFNS API. 2. The HSM Driver polls the DFNS API over mTLS and picks up the signing request with the payload. 3. The Driver retrieves the corresponding wrapped key from the database. 4. The Driver sends the wrapped key and payload to the HSM. The HSM unwraps the key in-memory, signs the payload, and returns the signature. 5. The Driver forwards the signature to your application. ## HSM Driver The HSM Driver is software provided by DFNS that bridges the DFNS API and your HSM. It has two primary functions: 1. **Polling DFNS APIs**: The HSM Driver continuously polls the DFNS API to retrieve requests for generating new keys or signing transactions. The connection is secured using mutual TLS (mTLS). 2. **Interfacing with HSMs via PKCS#11**: The HSM Driver translates API requests into PKCS#11 commands. This abstraction supports diverse HSM models without requiring specific hardware configurations. The HSM Driver is available as a Docker container image or a standalone binary. It can be co-located with the HSM or run on a separate host. ## Horizontal scaling and redundancy The architecture supports active-active configurations with multiple HSM + HSM Driver pairs: * **Queue-based load distribution**: The DFNS API maintains a request queue. Each HSM Driver independently polls for the next available job. Work is naturally distributed across all healthy instances. * **Fault tolerance**: If an HSM Driver or HSM fails, it stops polling. The remaining instances continue processing without interruption or manual failover. * **Automatic recovery**: A repaired HSM Driver simply resumes polling and re-joins the processing pool with no manual intervention. Requirements for scaling: * All HSMs must be provisioned with the **same master key**. * All HSM Driver instances must access the **same database**. HSM high-availability architecture ## Additional features When running HSM driver on your own infrastructure, additional features are available: * **[Validation gate](/advanced/deployment-models/validation-gate)**: Add a pre-signing authorization step where your HTTP handler approves or rejects every transaction before the signer proceeds. ## Deploying an HSM integration For the complete implementation guide, including prerequisites, mTLS certificate setup, HSM Driver configuration, RACI matrix, and operational procedures, contact our Support Team. # Deployment models Source: https://docs.dfns.co/advanced/deployment-models/index Compare DFNS deployment models for signing infrastructure: SaaS, dedicated, co-signer, HSM, and validation gate, to match your security needs. A deployment model simply defines **where your wallet's secret key shares are stored and operated**. It determines the balance of responsibility between DFNS and your organization, allowing you to choose the perfect setup for your security posture and business needs. We offer four primary deployment models, or a mix of them. Each provides the highest security level but varies in operational management and control. For your application integration, the DFNS API remains consistent across all deployment models. You can switch between models as your requirements evolve without changing your application code. ## Fully-managed MPC in DFNS Cloud This is the standard, default, and most popular option. In this model, DFNS securely manages all the key shares within our robust, geographically distributed cloud infrastructure. It's a turnkey solution that provides institutional-grade security with zero operational overhead for your team. * **You get:** Maximum convenience and the full security of the DFNS platform without managing any infrastructure. ## Hybrid MPC The Hybrid model offers a powerful balance of control and convenience. DFNS manages a portion of the key shares in our cloud, while your organization securely holds one or more shares within your own environment. This makes you a required participant in every signing ceremony, giving you a direct cryptographic veto over any transaction. In this model, you deploy and operate a Signing Server (provided by DFNS) within your infrastructure. This server securely stores your key share(s) and interfaces with DFNS during signing operations. * **You get:** Shared security responsibility and direct control over transaction finality. You can choose your preferred MPC threshold scheme (we recommend 3-out-of-5, but any configuration can be implemented) as well as how many signers are operated by DFNS versus your organization. ## On-Premise / Self-Hosted MPC For organizations with the strictest data residency, compliance, or infrastructure requirements, we offer a fully on-premise deployment. In this model, you run the DFNS signing software and manage all key shares entirely within your own data centers or private cloud. In this model, you are responsible for deploying, operating, and maintaining the entire signing infrastructure, including the Signing Server and key shares. DFNS provides the software and support, but all cryptographic operations occur within your controlled environment. * **You get:** Maximum control over your keys and infrastructure. You can choose your preferred MPC threshold scheme. We recommend 3-out-of-5, but any configuration can be implemented to match your security requirements. ## On-Premise HSM For organizations seeking to add a layer of physically-enforced, tamper-resistant security to your cryptographic operations, ensuring your key shares never leave the protected boundary of your hardware, **Hardware Security Modules (HSMs)** are the gold standard. DFNS supports integrating customer-owned HSMs. In this model, you deploy the HSMs and an HSM Driver that interfaces with your HSM using the PKCS#11 standard. The HSM Driver handles communication between DFNS and the HSM, ensuring that keys are securely managed and signing operations are performed within the HSM's protected environment. * **You get:** Key security with hardware-enforced protections and full control over your cryptographic environment. ## Cloud HSM Some organizations prefer to let the cloud infrastructure handles the HSM for them. In this model, you deploy only the HSM Driver that interfaces with the Cloud HSM using the PKCS#11 standard. The HSM Driver can be deployed on your premises or in the cloud, as long as it can connect the Cloud HSM and DFNS infrastructure. * **You get:** Key security with hardware-enforced protections without the hassle of HSM maintenance. ## Choosing the Right Model for You The best model depends on your specific needs for control versus convenience. The table below outlines the key differences to help you decide. | Feature | DFNS Cloud (Fully-Managed) | Hybrid Cloud | On-Premise (Self-Hosted) | | :-------------------- | :----------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------ | | **Key share storage** | All shares secured and stored by DFNS | Shared (DFNS & Customer) | All shares held by Customer | | **HSM Support** | No | No | Yes | | **Primary Benefit** | Simplicity & Speed | Shared Control & Veto Power | Maximum Control & Data Residency | | **Best For** | Most startups, fintechs, and enterprises that want to move fast without managing infrastructure. | Institutions that require a cryptographic role in transaction signing for compliance or internal policy. | Financial institutions or government entities with strict data locality rules or dedicated internal security teams. | ## Learn more * [MPC signing infrastructure](/advanced/deployment-models/mpc): architecture, flows, and threshold schemes for all MPC deployment options * [HSM signing infrastructure](/advanced/deployment-models/hsm): architecture and integration overview for Hardware Security Modules * [Validation gate](/advanced/deployment-models/validation-gate): pre-signing authorization for self-hosted signers * [Disaster recovery](/advanced/deployment-models/disaster-recovery): backup strategies and recovery options # MPC signing infrastructure Source: https://docs.dfns.co/advanced/deployment-models/mpc How DFNS uses Multi-Party Computation to secure wallet keys across cloud, hybrid, and self-hosted deployments without ever reconstructing the private key. DFNS uses Multi-Party Computation (MPC) to split wallet private keys into multiple shares, distributed across independent signers. No single signer ever holds the complete private key. Signing requires a threshold of signers to collaborate in a cryptographic ceremony, producing a valid signature without reconstructing the key. MPC is the default key management approach for all DFNS deployment models. The API, SDKs, policies, and features work identically regardless of where the signers run. ## Deployment options You choose where the signers run. DFNS supports three configurations: DFNS manages all signers in our geographically distributed cloud infrastructure. This is the default and most popular option. * All key shares are secured and stored by DFNS. * Zero operational overhead for your team. Fully-managed MPC architecture DFNS manages some signers in our cloud, you operate the rest in your own infrastructure. This makes you a required participant in every signing ceremony, giving you a cryptographic veto over any transaction. * You deploy and operate one or more DFNS signers on your infrastructure. * You choose the threshold split between DFNS and your organization. Hybrid MPC architecture You run all signers within your own data centers or private cloud. DFNS provides the software and API coordination, but all key shares remain under your control. * Maximum control over your keys and infrastructure. * You are responsible for all signer operations. Full on-premise MPC architecture You can choose your preferred MPC threshold scheme. We recommend 3-out-of-5, but any configuration can be implemented (e.g. 2-of-3, 4-of-7). ## Architecture The signer network consists of the following components: | Component | Description | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Signers** | DFNS signer software instances that hold key shares and participate in MPC ceremonies (key generation and signing). Each signer runs as a container or standalone process. | | **Delivery server** | Handles inter-signer communication during MPC ceremonies. In hybrid deployments, DFNS operates the delivery server. In full on-premise deployments, you host it. | | **Database** | Stores encrypted key shares. Each signer has its own database instance, ensuring no signer can access another's key shares and avoiding a single point of failure. | | **Encryption keys** | Keys used to encrypt and decrypt key shares at rest. When hosting signers on-premise, you manage these encryption keys. In the DFNS Cloud model, DFNS manages them. | ## Key generation Distributed Key Generation (DKG) is the ceremony where signers collaboratively generate key shares without any single party ever holding the complete private key. All signers in the scheme must participate. ```mermaid theme={null} sequenceDiagram participant App as Your application participant API as DFNS API participant DS as Delivery Server participant S as Each signer (Γ—n) participant DB as Database App->>API: Create wallet or key API->>S: DKG request S->>DS: MPC protocol exchanges DS-->>S: MPC protocol exchanges S->>DB: Store encrypted key share S-->>API: Public key API-->>App: Wallet created ``` 1. Your application requests a new wallet through the DFNS API. 2. The API initiates a DKG ceremony by contacting each participating signer. 3. Each signer generates its key share locally and communicates with other signers through the delivery server using mTLS. 4. Once the ceremony completes, each signer persists its encrypted key share in its database. 5. The public key is returned to your application. ## Transaction signing Only the threshold number of signers need to participate in a signing ceremony. ```mermaid theme={null} sequenceDiagram participant App as Your application participant API as DFNS API participant DS as Delivery Server participant S as Each signer (Γ—t) participant DB as Database App->>API: Sign transaction API->>S: Signing request + payload S->>DB: Retrieve encrypted key share DB-->>S: Encrypted key share S->>DS: MPC signing protocol exchanges DS-->>S: MPC signing protocol exchanges S-->>API: Threshold signature API-->>App: Transaction signed ``` 1. Your application submits a transaction through the DFNS API. 2. The API initiates a signing ceremony with the required threshold of signers. 3. Each participating signer retrieves its encrypted key share, decrypts it, and participates in the MPC signing protocol via the delivery server. 4. The threshold signature is produced without any single signer holding the complete private key. 5. The signature is returned to your application. ## Threshold schemes The threshold scheme (`t`-out-of-`n`) determines: | Property | Effect | | ------------------------ | ------------------------------------------------------------------ | | **Signing availability** | Only `t` out of `n` signers need to be online to sign. | | **Fault tolerance** | Up to `n - t` signers can be offline without affecting operations. | | **Security** | An attacker must compromise `t` signers to reconstruct a key. | In a hybrid deployment, you decide how many signers are operated by DFNS versus your organization. For example, in a 3-of-5 scheme, you could host 2 signers and DFNS hosts 3. Neither party alone can sign without the other's participation. ## Additional features When running signers on your own infrastructure, additional features are available: * **[Validation gate](/advanced/deployment-models/validation-gate)**: Add a pre-signing authorization step where your HTTP handler approves or rejects every transaction before the signer proceeds. * **[Layer 4 disaster recovery](/advanced/deployment-models/disaster-recovery#layer-4-disaster-recovery)**: Automatically encrypt key share backups with your own public key and store them in your S3 bucket for independent recovery. ## Deploying signers on your infrastructure If you choose the hybrid or on-premise model, you will deploy and operate DFNS signers in your environment. For the complete implementation guide, including prerequisites, mTLS certificate setup, signer configuration, and operational procedures, contact our Support Team. Self-hosted signers support several key isolation and keystore configurations depending on your security and operational requirements. The available options are not all covered in the public documentation. Contact our Support Team to discuss which setup fits your deployment. # Validation gate Source: https://docs.dfns.co/advanced/deployment-models/validation-gate Add a pre-signing authorization step where your HTTP handler approves or rejects every DFNS signing request before it reaches the signers. The validation gate is an optional feature for customers running [signers](/advanced/deployment-models) on their own infrastructure. When enabled, the signer sends an HTTP request to an endpoint you control before performing a signature or key export. If your handler returns `200 OK`, the operation proceeds. Any other response rejects it. This gives you full control over which operations your signers are allowed to perform, based on your own business logic. ## How it works A signing or key export request reaches the signer through the normal DFNS flow. Before performing the operation, the signer sends an HTTP `POST` request with a JSON body to the URL you configured. The payload contains information about the operation (see [Request payload](#request-payload) below). Your handler inspects the payload and returns: * `200 OK` to approve the operation * Any other status code to reject it If approved, the signer proceeds with the signing or key export. If rejected, the operation fails and the rejection is propagated back to the caller. ## Request payload Your handler receives a `POST` request with a JSON body. ### `signerInfo` fields The `signerInfo` object contains trusted information provided by the signer itself. These values are derived from the signer's own state and are not user-supplied. | Field | Type | Description | | :----------------- | :--------------------------- | :-------------------------------------------------------------------------------------------------------------------------------- | | `kind` | `"Signing"` or `"KeyExport"` | The type of operation being performed. | | `key_id` | string | ID of the key being used. | | `public_key` | string | Hex-encoded public key associated with the key. | | `tx_hash` | string (optional) | Hex-encoded digest of the payload to be signed. Present for signing requests, absent for key exports. | | `derivation_path` | array of numbers (optional) | HD derivation path, when the key uses hierarchical derivation. | | `child_public_key` | string (optional) | Hex-encoded child public key derived from the master key using the `derivation_path`. Present only when `derivation_path` is set. | ### Examples Signing request with HD derivation: ```json theme={null} { "signerInfo": { "tx_hash": "a1b2c3d4e5f6...", "kind": "Signing", "key_id": "key-abc-123", "public_key": "04abcdef...", "derivation_path": [44, 60, 0, 0, 0], "child_public_key": "04fedcba..." } } ``` Key export request: ```json theme={null} { "signerInfo": { "kind": "KeyExport", "key_id": "key-abc-123", "public_key": "04abcdef..." } } ``` ## Response handling Your handler must return `200 OK` to approve the operation. The signer treats any other response as a rejection: | Your handler returns | Signer behavior | | :----------------------- | :-------------------------------------------- | | `200 OK` | Operation approved. Signer proceeds. | | `400 Bad Request` | Rejected. Treated as an authentication error. | | `401 Unauthorized` | Rejected. Treated as an authentication error. | | Any other non-200 status | Rejected. Treated as permission denied. | | Connection failure | Rejected. Treated as an internal error. | When your handler rejects a request, return a meaningful response body. The signer includes it in the error message propagated to the caller. ## Setup The validation gate is configured as part of the signer deployment. For configuration options (CLI flags, environment variables) and security options (HMAC shared secret, mTLS), contact our Support Team. # Governance architecture Source: https://docs.dfns.co/advanced/governance-architecture How DFNS combines authentication, permissions, policies, and MPC signing into a layered governance model for secure wallet operations. This page explains how DFNS' governance layers work together to secure your digital assets. ## Overview Every DFNS API request passes through multiple security layers before a blockchain transaction is signed: ```mermaid theme={null} flowchart TB App[Your Application] subgraph Auth[1: Authentication] AuthCheck["Verify API token
Verify user action signature"] end subgraph Authz[2: Authorization] PermCheck["Check user permissions
e.g., Wallets:Sign"] end subgraph Policy[3: Policy Engine] PolicyEval["Evaluate matching policies"] end Blocked([Blocked]) ApprovalRequired["Approval Required"] HumanApproval{"Human Review"} Rejected([Rejected]) Approved["Approved"] subgraph MPC[4: MPC Signing] MPCSign["Distributed key shares
sign collaboratively"] end subgraph Broadcast[5: Broadcast] BroadcastTx["Send to blockchain"] end App --> Auth Auth --> Authz Authz --> Policy Policy --> Blocked Policy --> ApprovalRequired Policy --> MPC ApprovalRequired --> HumanApproval HumanApproval -->|Reject| Rejected HumanApproval -->|Approve| Approved Approved --> MPC MPC --> Broadcast ``` ## Layer 1: Authentication Every API request must prove identity through two mechanisms: ### API Token The `Authorization: Bearer ` header identifies who is making the request: * **User tokens**: Short-lived, obtained through login flow * **Service account tokens**: Long-lived, for server-to-server communication * **Personal access tokens**: Long-lived user tokens for development ### User Action Signature For state-changing operations (POST, PUT, DELETE), the `X-DFNS-USERACTION` header proves the caller controls a registered credential: 1. Client requests a challenge from DFNS 2. Client signs the challenge with their credential (passkey or asymmetric key) 3. DFNS verifies the signature matches a registered credential This ensures that even if a token is stolen, an attacker cannot perform sensitive operations without the credential. The challenge you sign binds the exact request you are authorizing: a hash of the request body, the HTTP method, the path, and a server-generated human-readable summary of the action (for example, "Transfer Native asset to recipient 0x..."). DFNS recomputes and re-verifies these when you submit the signed action, so a request that no longer matches what was signed (different recipient, amount, path, or method) is rejected. Your signature is bound to a specific intent, not just to "some request." ## Layer 2: Authorization (Permissions) After authentication, DFNS checks if the user has permission to perform the requested action. Permissions follow a whitelist model - users can only perform actions explicitly granted: ```mermaid theme={null} flowchart LR User --> Permission --> Operations ``` Example: A user with `Wallets:Read` can view wallets but cannot transfer assets (requires `Wallets:Sign`). See [Permissions](/core-concepts/roles-and-permissions) for the full list. ## Layer 3: Policy Engine Even with valid authentication and permissions, the Policy Engine can add additional controls: | Policy action | Effect | | ----------------- | -------------------------------------------------------- | | `Block` | Transaction is rejected | | `RequestApproval` | Transaction held until humans approve | | `NoAction` | Transaction proceeds (used with Chainalysis for logging) | Policies evaluate rules like: * Transaction amount limits * Velocity limits (amount or count over time) * Recipient whitelisting * Chainalysis screening **Important:** All matching policies are evaluated for every activity. If multiple policies apply: * Any `Block` result immediately blocks the activity * Multiple `RequestApproval` results require approvals from all triggered policies * Policies cannot bypass or override each other See [Policies](/core-concepts/policies) for details. ## Layer 4: MPC Signing Once a transaction passes all checks, the MPC signing ceremony begins: ```mermaid theme={null} flowchart TB subgraph MPC["DFNS MPC Network"] direction TB subgraph Signers[" "] direction LR S1["Signer Node
Share 1"] S2["Signer Node
Share 2"] S3["Signer Node
Share 3"] S4["Signer Node
Share 4"] end Threshold["Threshold Signature
(k-of-n nodes collaborate)"] S1 --> Threshold S2 --> Threshold S3 --> Threshold S4 --> Threshold end ``` Key properties: * **No complete key**: The private key never exists in one place * **Threshold security**: Requires k-of-n shares to sign (not all shares needed) * **Geographic distribution**: Nodes are in different data centers/regions * **Audit trail**: Every signing ceremony is logged ## Layer 5: Broadcast The signed transaction is broadcast to the blockchain network. DFNS monitors for confirmation and updates transaction status. ## Security model summary | Layer | What it protects against | | ------------------- | -------------------------------------------------------------- | | Authentication | Unauthorized access | | User action signing | Token theft, replay attacks, tampering with the signed request | | Permissions | Privilege escalation | | Policies | Unauthorized transactions, fraud | | MPC | Key theft, single point of compromise | ## Separation of concerns A critical security property: **credentials and keys are completely separate**. | Credential (Authentication) | Key (Signing) | | ----------------------------------------------------------- | ----------------------------- | | Proves identity | Signs transactions | | Stored on user device (passkey) or server (service account) | Stored in MPC network | | Can be revoked/rotated | Key shares are immutable | | Compromised credential β‰  stolen assets | Protected by all layers above | Even if an attacker steals credentials, they still face: * User action signing requirements * Permission checks * Policy enforcement * MPC threshold requirements ## Trust boundaries The layers above describe how a single request is authorized. This section describes who you have to trust, and how to verify operations independently of that trust. DFNS operates as the **maker**: it builds the transaction from your request and submits it to the signers. You can operate as the **checker**: you independently verify what is about to be signed, and approve or reject it. A checker step lets you detect a tampered transaction in both directions: * **If DFNS were compromised**, your checker sees a transaction that does not match the intent you authorized, and rejects it. * **If your initiating workstation were compromised**, the transaction is checked again before signing, so tampering is caught even though it originated on your own machine. This is distinct from separation of duties *within* your organization, where the initiator and the approver are different members of your team (see [govern wallet access](/solutions/govern-wallet-access)). Trust boundaries are about verifying DFNS and your own endpoints, not only your team members. DFNS gives you two places to insert a checker: | Checker | When it runs | What it is | | :------------------------------------------------------------- | :---------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Policy approval](/core-concepts/policies) | Asynchronous: after the request, before signing | A policy with `RequestApproval` holds the operation and notifies an approver with the transaction details. The approver is a human reviewing on a separate device, or a service account running your own automated checks. They approve or reject out of band. | | [Validation gate](/advanced/deployment-models/validation-gate) | Synchronous: immediately before signing | Self-hosted signers call an HTTP handler you control before signing, passing a digest of the payload to be signed plus key details. Return `200 OK` to allow, anything else to reject. | ### Threat model Each row assumes the worst case at one location and shows which checker catches a tampered transaction. | Assume compromised | Example | What catches it | | :------------------------------------- | :------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Your workstation, browser, or local UI | The UI shows "send 1 BTC to B" but submits "send 1 BTC to X" | DFNS builds the transaction from the request it received. A policy approver reviewing on a separate device sees recipient X and rejects. A validation gate handler can compare the signing request against the transaction your systems expect and reject the mismatch. A [trusted display](#trusted-display-wysiwys) lets the operator catch X at signing time. | | DFNS | You authorize "send to B" but DFNS builds "send to X" | A checker running on your own infrastructure detects that the transaction does not match the intent you authorized, and rejects it before or at signing. | | Your own checker infrastructure | Your validation gate handler and approver are both compromised | DFNS is healthy and builds the transaction faithfully from the intent you authorized, so "send to B" stays "send to B". | No single party, whether DFNS, your workstation, or your checker, can unilaterally produce a malicious signed transaction without another layer detecting it. ### Trusted display (WYSIWYS) The human-readable summary bound into the [user action signature](/api-reference/auth/signing-flows) is what makes "what you see is what you sign" (WYSIWYS) possible: the operator signs a description of the action, not an opaque blob. For this to defend against a compromised client, the summary must be shown to the operator on a surface that the client's own code cannot alter. The standards for this in the browser, such as Secure Payment Confirmation, are still emerging and support is currently limited. ## Related Deep dive into MPC technology Configuring transaction policies Understanding permission model Authentication flows # Key import and export Source: https://docs.dfns.co/advanced/key-import-and-export Import existing private keys into DFNS or export keys from DFNS using secure ceremonies that protect material in transit and at rest. DFNS secures private keys by generating them as MPC key shares in our decentralized key management network. This happens by default when you [create a wallet](/api-reference/wallets/create-wallet). In some circumstances, you may need to import an existing private key or export a key from DFNS. **Import is not the same as activate.** *Import* brings an existing external private key into DFNS MPC (this page). *[Activate wallet](/api-reference/wallets/activate-wallet)* is an unrelated blockchain-level step that deploys or registers a DFNS-created account on-chain for networks that require it (e.g., Starknet, Canton, Concordium). You do not import a wallet to activate it, and you do not activate an imported key. ## Import **We recommend creating new wallets and transferring funds instead of importing keys.** Imported keys are inherently less secure because they existed in complete form before import. You cannot verify how the key was stored, handled, or who may have had access to it. Keys generated natively by DFNS MPC have never existed as a complete key and provide stronger security guarantees. DFNS uses MPC (Multi-Party Computation) to secure keys. When you import a key, the SDK processes it entirely on your machine using WebAssembly: 1. **Fetch signers** - The SDK retrieves DFNS signer nodes and their public keys 2. **Split locally** - Your private key is split into shares using threshold cryptography 3. **Encrypt for signers** - Each share is encrypted with the corresponding signer's public key 4. **Transmit shares** - Only encrypted shares are sent to DFNS The complete private key never leaves your machine and never exists on DFNS servers. Once imported, the key operates like any DFNS-native key with full MPC security for signing operations. For detailed import instructions including vendor-specific migration steps, see the developer guide. ### After importing a key Once you've imported a key, you can: * **Create wallets from it**: Use [Create Wallet](/api-reference/wallets/create-wallet) with `signingKey.id` to create wallets on specific networks * **Sign directly**: Use the [Signing API](/api-reference/sign) for raw signatures * **Multi-chain usage**: The same key can be used across compatible networks (e.g., all EVM chains share the same address) ### When to import vs create new **Import makes sense when:** * The wallet address is tied to a smart contract you can't redeploy * You have regulatory requirements to maintain specific addresses * The address has non-transferable assets (certain NFTs, protocol permissions) **Create new keys instead when:** * Starting fresh with no legacy requirements * High-value production wallets * You can move assets from old wallets ## Export Export a key from DFNS to use it outside the platform β€” either to [migrate it to another provider](/guides/developers/export-keys), or to hold an [independent backup](/advanced/deployment-models/disaster-recovery#manual-key-backup-key-export) for disaster recovery. The ceremony below is the same for both. DFNS cannot guarantee the security of transactions signed with exported keys. Once a key leaves DFNS, its security is entirely your responsibility. The export process is the reverse of import. The SDK runs entirely on your machine using WebAssembly: 1. **Generate a keypair** - You provide a public key that the MPC signers will use to encrypt their shares 2. **Encrypted download** - Each signer encrypts its key share with your public key and sends it to your machine 3. **Local reconstitution** - The SDK decrypts the shares and reconstitutes the full private key locally The complete private key only exists on your machine at the end of this process. It is never assembled on DFNS servers. The encryption in step 1-2 protects the shares in transit. The reconstituted key itself is not encrypted. If you need to store it, you are responsible for encrypting it at rest. See the [export SDK example](https://github.com/dfns/dfns-sdk-ts/tree/m/examples/sdk/export-wallet) for implementation details. Export a key and confirm it works, including an offline signing test. ## Related Understanding the difference between keys and wallets Import SDK implementation examples # Create Address Watch Source: https://docs.dfns.co/api-reference/address-watches/create-address-watch /openapi.yaml post /address-watches Registers an on chain address to watch. An address watch is not controlled by Dfns: it holds no key, it cannot sign or move funds. The indexer matches on chain activity touching the address and sends the corresponding webhooks. The address must already exist on chain and is normalized to the form the indexer matches on (lowercase for EVM networks). Only networks that support address watches are accepted. A given address can only be watched once per network within an organization while the watch is Active. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `AddressWatches:Create`: Always required. # Get Address Watch Source: https://docs.dfns.co/api-reference/address-watches/get-address-watch /openapi.yaml get /address-watches/{addressWatchId} Retrieves an address watch by its ID. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `AddressWatches:Read`: Always required. # Get Address Watch Assets Source: https://docs.dfns.co/api-reference/address-watches/get-address-watch-assets /openapi.yaml get /address-watches/{addressWatchId}/assets Retrieves the list of assets held by the address watch, as tracked by the indexer. Balances are tracked from the moment the watch is created. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `AddressWatches:Read`: Always required. # Get Address Watch Blockchain Events Source: https://docs.dfns.co/api-reference/address-watches/get-address-watch-blockchain-events /openapi.yaml get /address-watches/{addressWatchId}/blockchain-events Retrieves a list of decoded blockchain events indexed for the specified address watch. Blockchain events are not value transfers: asset and token transfers are listed by [Get Address Watch History](https://docs.dfns.co/api-reference/address-watches/get-address-watch-history) instead. Events from the same transaction share the same `txHash` across both lists. Items are sorted by descending block number; within one block the item order is not the on-chain order. `index` is the block scoped log index as a decimal string: sort by `blockNumber` and the numeric value of `index` to recover the on-chain order. Webhook delivery is at-least-once and unordered; use `id` to deduplicate. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `AddressWatches:Read`: Always required. # Get Address Watch History Source: https://docs.dfns.co/api-reference/address-watches/get-address-watch-history /openapi.yaml get /address-watches/{addressWatchId}/history Retrieves the list of indexed on chain activities for the specified address watch. The list reflects the indexed on chain activity from the moment the watch was created. Events from before the watch are not backfilled. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `AddressWatches:Read`: Always required. # List Address Watches Source: https://docs.dfns.co/api-reference/address-watches/list-address-watches /openapi.yaml get /address-watches Retrieves the list of address watches in your organization. Pagination is supported via limit and paginationToken parameters. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `AddressWatches:Read`: Always required. # Agreements Source: https://docs.dfns.co/api-reference/agreements Programmatically accept DFNS and third-party provider service agreements, privacy policies, and terms of service required for certain features. Some DFNS services require an explicit agreement acceptance before they can be used. The agreements API allows you to programmatically view and sign these agreements ### Supported Agreements The list below shows which agreements types are available on the API. | Agreement Type | Description | | --------------------- | -------------------------------------------------------------------------------------- | | UniswapTermsOfService | The terms of service to use the UniswapClassic and UniswapX providers on the Swaps API | | UniswapPrivacyPolicy | The privacy policy to use the UniswapClassic and UniswapX providers on the Swaps API | ## Agreement object # Get Latest Unaccepted Agreement Source: https://docs.dfns.co/api-reference/agreements/get-latest-unaccepted-agreement /openapi.yaml get /agreements/latest-unaccepted Get the latest unaccepted agreement for a specific agreement type #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Agreements:Acceptance:Read`: Always required. # Record Agreement Acceptance Source: https://docs.dfns.co/api-reference/agreements/record-agreement-acceptance /openapi.yaml post /agreements/{agreementId}/accept Record the acceptance of a specific agreement by its ID #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Agreements:Acceptance:Create`: Always required. # Allocations API Source: https://docs.dfns.co/api-reference/allocations Reference for the DFNS Allocations API, which lets you earn rewards on your crypto holdings through integrated rewards providers across supported chains. ## Providers | Provider | Description | Supported chains | | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | | M0 | Offers the `0fns` protocol, an extension to the M0 USD-based stablecoin \$M that offers rewards to holders. With 0fns you can trade your USDC on Ethereum into 0fns and begin earning rewards right away. | Ethereum Mainnet, Ethereum Sepolia | | Yield.xyz | Offers a set of DeFi vault strategies, each with its own APY. You deposit the vault's underlying token and can withdraw it at any time. | Ethereum Mainnet, Base | ## Protocols The `protocol` field of an allocation identifies the strategy it deposits into: | `protocol` value | Provider | Strategy | Deposit asset | Network | | ----------------------- | --------- | --------------------------------- | ------------- | -------- | | `0fns` | M0 | 0fns | USDC | Ethereum | | `SkySusds` | Yield.xyz | Sky Savings Rate (sUSDS) | USDS | Ethereum | | `GauntletUsdcPrime` | Yield.xyz | Gauntlet USDC Prime (gtUSDC) | USDC | Ethereum | | `SteakhouseUsdt` | Yield.xyz | Steakhouse USDT (steakUSDT) | USDT | Ethereum | | `GauntletUsdcPrimeBase` | Yield.xyz | Gauntlet USDC Prime (gtUSDCp) | USDC | Base | | `SteakhouseUsdcBase` | Yield.xyz | Steakhouse USDC (steakUSDC) | USDC | Base | | `SentoraPyusdMain` | Yield.xyz | Sentora PYUSD Main (senPYUSDMain) | PYUSD | Ethereum | Yield.xyz vaults are available on mainnet networks only. For a product-level overview, see [Allocations](/features/allocations). ## Flow Overview 1. **Create an Allocation position**: Create a new allocation position by depositing/trading assets into the Allocations protocol. 2. **Track Status**: Monitor the Allocation position execution. 3. **Increase/Decrease position**: Add or remove assets from an existing Allocation position. ## Allocation object # Create Allocation Source: https://docs.dfns.co/api-reference/allocations/create-allocation /openapi.yaml post /allocations Create a new allocation. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Allocations:Create`: Always required\ `Wallets:Transactions:Create`: Always required. Allocation transactions are broadcast from your wallet.\ `FeeSponsors:Use`: Required if `feeSponsorId` is specified and the sponsoree wallet belongs to an `EndUser` user kind. # Create Allocation Action Source: https://docs.dfns.co/api-reference/allocations/create-allocation-action /openapi.yaml post /allocations/{allocationId}/actions Create a new action for an existing allocation. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Allocations:Update`: Always required\ `Wallets:Transactions:Create`: Always required. Allocation transactions are broadcast from your wallet.\ `FeeSponsors:Use`: Required if `feeSponsorId` is specified and the sponsoree wallet belongs to an `EndUser` user kind. # Get Allocation Source: https://docs.dfns.co/api-reference/allocations/get-allocation /openapi.yaml get /allocations/{allocationId} Retrieve the details of a specific allocation. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Allocations:Read`: Always required. # Get Allocations Info Source: https://docs.dfns.co/api-reference/allocations/get-allocations-info /openapi.yaml get /allocations/info Retrieve the current reward rate (APY) for each supported allocation protocol. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Allocations:Read`: Always required. # List Allocation Actions Source: https://docs.dfns.co/api-reference/allocations/list-allocation-actions /openapi.yaml get /allocations/{allocationId}/actions Retrieve the list of actions for a specific allocation. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Allocations:Read`: Always required. # List Allocations Source: https://docs.dfns.co/api-reference/allocations/list-allocations /openapi.yaml get /allocations Lists the allocations of your organization. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Allocations:Read`: Always required. # Account recovery Source: https://docs.dfns.co/api-reference/auth/account-recovery API endpoints to recover access to a DFNS user account when a passkey or device is lost, using recovery codes and verification flows. Users can recover their DFNS accounts using recovery credentials. When a recovery credential is used, all existing credentials (both regular and recovery) are invalidated for security. The user must create new credentials during the recovery process. A recovery credential is an encrypted private key that DFNS stores on your behalf. The encryption is performed by the frontend that created the credential, so DFNS never has access to the decryption password. This means recovery must happen through the same frontend that registered the credential: * **Dashboard users**: If the user registered through the DFNS dashboard, they recover via the dashboard at [app.dfns.io/recover](https://app.dfns.io/recover). * **End users on your app**: If the user registered through your application (delegated registration), you must implement the recovery flow in your application using the recovery APIs. DFNS provides the APIs; you own the recovery UX and encryption scheme. **For end users on your app, recovery is not optional.** If a user loses their only credential and you never registered a recovery credential or prompted them to add a second device, their wallet is permanently inaccessible. Your only fallback is manual delegated recovery, one user at a time. Register a `recoveryCredential` at signup. See [Implement end-user recovery](/guides/developers/end-user-recovery). ## Guides Step-by-step guide for employees to recover their account using the dashboard. Developer guide for implementing recovery flows for delegated wallet users. ## Related endpoints * /auth/recover/init – [Create recovery challenge](/api-reference/auth/create-recovery-challenge) * /auth/recover/user/delegated – [Create delegated recovery challenge](/api-reference/auth/create-delegated-recovery-challenge) * /auth/recover/user – [Recover user](/api-reference/auth/recover-user) # Activate Credential Source: https://docs.dfns.co/api-reference/auth/activate-credential /openapi.yaml put /auth/credentials/activate Activates a credential that was previously deactivated. If the credential is already activated no action is taken. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ ❌ Service Account #### Required Permissions No permission required. # Activate Personal Access Token Source: https://docs.dfns.co/api-reference/auth/activate-personal-access-token /openapi.yaml put /auth/pats/{tokenId}/activate Activate a specific Personal Access Token. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions No permission required. # Activate Service Account Source: https://docs.dfns.co/api-reference/auth/activate-service-account /openapi.yaml put /auth/service-accounts/{serviceAccountId}/activate Activate a specific Service Account. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ βœ… Service Account #### Required Permissions `Auth:ServiceAccounts:Activate`: Always required. # Activate User Source: https://docs.dfns.co/api-reference/auth/activate-user /openapi.yaml put /auth/users/{userId}/activate Activate a specific User. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ βœ… Service Account #### Required Permissions `Auth:Users:Activate`: Always required. # Complete End User Registration with Wallets Source: https://docs.dfns.co/api-reference/auth/complete-end-user-registration-with-wallets /openapi.yaml post /auth/registration/enduser Completes the end user registration process and creates the user's initial credentials along with delegated wallets for the new end user. All credentials submitted in this call (`firstFactorCredential`, `secondFactorCredential`, `recoveryCredential`) sign the same challenge returned by the registration init endpoint ([Create Delegated Registration Challenge](https://docs.dfns.co/api-reference/auth/create-delegated-registration-challenge) or [Create Social Registration Challenge](https://docs.dfns.co/api-reference/auth/create-social-registration-challenge)). Always include a `recoveryCredential` for end users. Without one, a user who loses their device cannot recover access and you must initiate a delegated recovery manually. See [Implement end-user recovery](https://docs.dfns.co/guides/developers/end-user-recovery). The type of credentials being registered is determined by the `credentialKind` field in the nested objects (`firstFactorCredential` , `secondFactorCredential` and `recoveryCredential`). Supported credential kinds are: * `Fido2`: User action is signed by a user's signing device using `WebAuthn`. * `Key`: User action is signed by a user's, or token's, private key. * `PasswordProtectedKey`: User action is signed by a user's, or token's, private key. The encrypted version of the private key is stored by Dfns and returns during the signing flow for the user to decrypt it. * `RecoveryKey`: Similar to `PasswordProtectedKey`, but this credential can only be used to recover an account, not to sign an action or login. Once this credential is used, all the other user's credentials are invalidated. The number of delegated wallets created and the wallet types are determined by the `wallets` specifications. The end user is automatically assigned `ManagedDefaultEndUserAccess` managed permission that grants the end user full access to the wallets. #### Authentication ❌ Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ ❌ Service Account\ βœ… Registration Code #### Required Permissions No permission required. # Complete OIDC Login Source: https://docs.dfns.co/api-reference/auth/complete-oidc-login /openapi.yaml post /auth/login/oidc Completes the OIDC login process by exchanging the authorization code obtained from the identity provider. If the verified user has no active first-factor credential yet, it returns a registration challenge to complete via [Complete User Registration](/api-reference/auth/complete-user-registration); otherwise it returns the user's authentication token. #### Authentication No authentication required. #### Required Permissions No authentication required. # Complete SSO Login Source: https://docs.dfns.co/api-reference/auth/complete-sso-login /openapi.yaml post /auth/login/sso Completes the SSO login process by exchanging the authorization code obtained from the identity provider for the user's authentication token. #### Authentication No authentication required. #### Required Permissions No authentication required. # Complete User Login Source: https://docs.dfns.co/api-reference/auth/complete-user-login /openapi.yaml post /auth/login Completes the login process and provides the authenticated user with their authentication token. The type of credentials used to login is determined by the `kind` field in the nested objects (`firstFactor` and `secondFactor`). Supported credential kinds are: * `Fido2`: Login challenge is signed by a user's signing device using `WebAuthn`. * `Key`: Login challenge is signed by a user's private key. * `PasswordProtectedKey`: Login challenge is signed by the decrypted user's private key that was sent during the [Create Login Challenge](https://docs.dfns.co/api-reference/auth/create-login-challenge) step. #### Authentication No authentication required. #### Required Permissions No authentication required. # Complete User Registration Source: https://docs.dfns.co/api-reference/auth/complete-user-registration /openapi.yaml post /auth/registration Completes the user registration process and creates the user's initial credentials. All credentials submitted in this call (`firstFactorCredential`, `secondFactorCredential`, `recoveryCredential`) sign the same challenge returned by the registration init endpoint ([Create Registration Challenge](https://docs.dfns.co/api-reference/auth/create-registration-challenge), [Create Delegated Registration Challenge](https://docs.dfns.co/api-reference/auth/create-delegated-registration-challenge), or [Create Social Registration Challenge](https://docs.dfns.co/api-reference/auth/create-social-registration-challenge)). Always include a `recoveryCredential` for end users. Without one, a user who loses their device cannot recover access and you must initiate a delegated recovery manually. See [Implement end-user recovery](https://docs.dfns.co/guides/developers/end-user-recovery). The type of credentials being registered is determined by the `credentialKind` field in the nested objects (`firstFactorCredential` , `secondFactorCredential` and `recoveryCredential`). Supported credential kinds are: * `Fido2`: User action is signed by a user's signing device using `WebAuthn`. * `Key`: User action is signed by a user's, or token's, private key. * `PasswordProtectedKey`: User action is signed by a user's, or token's, private key. The encrypted version of the private key is stored by Dfns and returns during the signing flow for the user to decrypt it. * `RecoveryKey` : Similar to `PasswordProtectedKey`, but this credential can only be used to recover an account not to sign an action or login. Once this credential is used all the other user's credentials are invalidated. #### Authentication ❌ Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ ❌ Service Account\ βœ… Registration Code #### Required Permissions No permission required. # Create Credential Source: https://docs.dfns.co/api-reference/auth/create-credential /openapi.yaml post /auth/credentials Part of the flow [Create Credential Regular flow](https://docs.dfns.co/api-reference/auth/credentials#regular-flow). Adds a new credential to a user's account. See [Credential Kinds](https://docs.dfns.co/api-reference/auth/credentials#credential-kinds) for all supported credential types. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ ❌ Service Account #### Required Permissions No permission required. # Create Credential Challenge Source: https://docs.dfns.co/api-reference/auth/create-credential-challenge /openapi.yaml post /auth/credentials/init Part of the flow [Create Credential Regular flow](https://docs.dfns.co/api-reference/auth/credentials#regular-flow). Starts a create user credential session, returning a challenge that will be used to verify the user's identity. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ ❌ Service Account #### Required Permissions No permission required. # Create Credential Challenge With Code Source: https://docs.dfns.co/api-reference/auth/create-credential-challenge-with-code /openapi.yaml post /auth/credentials/code/init Part of the flow [Create Credential With Code](https://docs.dfns.co/api-reference/auth/credentials#create-credential-with-code-flow). Creates a credential challenge using a one time code-time-code. This challenge must then be signed by the new credential, before finalizing the flow. #### Authentication No authentication required. #### Required Permissions No authentication required. # Create Credential Code Source: https://docs.dfns.co/api-reference/auth/create-credential-code /openapi.yaml post /auth/credentials/code Part of the [Create Credential With Code flow](https://docs.dfns.co/api-reference/auth/credentials#create-credential-with-code-flow). Creates a one-time-code that can then be used to create a new credential from a place you don't have access to one of your existing credential. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ ❌ Service Account #### Required Permissions No permission required. # Create Credential With Code Source: https://docs.dfns.co/api-reference/auth/create-credential-with-code /openapi.yaml post /auth/credentials/code/verify Finalizes the flow [Create Credential With Code](https://docs.dfns.co/api-reference/auth/credentials#create-credential-with-code-flow). Adds a new credential to a user's account. This endpoint is similar to the [Create Credential](https://docs.dfns.co/api-reference/auth/create-credential) endpoint, except: * it does not need the user to be authenticated * it does not need user action signing * it will only work with the challenge gotten from the [Create Credential Challenge With Code](https://docs.dfns.co/api-reference/auth/create-credential-challenge-with-code) endpoint #### Authentication No authentication required. #### Required Permissions No authentication required. # Create Delegated Recovery Challenge Source: https://docs.dfns.co/api-reference/auth/create-delegated-recovery-challenge /openapi.yaml post /auth/recover/user/delegated Only a [Service Account](https://docs.dfns.co/api-reference/auth/service-accounts) can use this endpoint. Starts a recovery session for an end user under your brand, without sending a Dfns recovery email. Call this after you have verified the user's identity with your own auth system. The response returns a recovery challenge. Pass it to your frontend so the user can decrypt their recovery credential and sign, then call [Recover User](https://docs.dfns.co/api-reference/auth/recover-user) to complete the recovery and register fresh credentials. #### Authentication ❌ Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Auth:Recover:Delegated`: Always required. # Create Delegated Registration Challenge Source: https://docs.dfns.co/api-reference/auth/create-delegated-registration-challenge /openapi.yaml post /auth/registration/delegated Only a [Service Account](https://docs.dfns.co/api-reference/auth/service-accounts) can use this endpoint. Registers a new End User in your organization and returns a registration challenge, without sending a Dfns registration email. Use this when your application owns the authentication system and you want delegated signing under your brand. The response includes: 1. A new `EndUser` attached to your organization. 2. A registration challenge plus a `temporaryAuthenticationToken` to authenticate the next call. Pass the challenge to your frontend so the user can create a passkey, then call [Complete User Registration](https://docs.dfns.co/api-reference/auth/complete-user-registration) or [Complete End User Registration with Wallets](https://docs.dfns.co/api-reference/auth/complete-end-user-registration-with-wallets) with that challenge signed. Bundle a `recoveryCredential` in the completion call alongside the first passkey. All credentials in that call sign the same challenge returned here. See [Implement end-user recovery](https://docs.dfns.co/guides/developers/end-user-recovery). #### Authentication ❌ Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions `Auth:Register:Delegated`: Always required. # Create Login Challenge Source: https://docs.dfns.co/api-reference/auth/create-login-challenge /openapi.yaml post /auth/login/init Start a user login session, returning a challenge that will be used to verify the user's identity. If the user has a credential of kind `PasswordProtectedKey` a temporary one time code needs to be passed in the `loginCode` field. If the user has at least one discoverable WebAuthn credential, `username` is optional (username-less flow). #### Authentication No authentication required. #### Required Permissions No authentication required. # Create Personal Access Token Source: https://docs.dfns.co/api-reference/auth/create-personal-access-token /openapi.yaml post /auth/pats Create a new Personal Access Token for the caller. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ ❌ Service Account #### Required Permissions `Auth:Pats:Create`: Always required. # Create Recovery Challenge Source: https://docs.dfns.co/api-reference/auth/create-recovery-challenge /openapi.yaml post /auth/recover/user/init Starts a user recovery session, returning a challenge that will be used to verify the user's identity. #### Authentication No authentication required. #### Required Permissions No authentication required. # Create Registration Challenge Source: https://docs.dfns.co/api-reference/auth/create-registration-challenge /openapi.yaml post /auth/registration/init Starts a user registration session. It returns a challenge that will need to be signed by a passkey and used to perform the step [Complete User Registration](/api-reference/auth/complete-user-registration) #### Authentication No authentication required. #### Required Permissions No authentication required. # Create Service Account Source: https://docs.dfns.co/api-reference/auth/create-service-account /openapi.yaml post /auth/service-accounts Create a new Service Account for your organization. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ ❌ Service Account #### Required Permissions `Auth:ServiceAccounts:Create`: Always required. # Create Social Registration Challenge Source: https://docs.dfns.co/api-reference/auth/create-social-registration-challenge /openapi.yaml post /auth/registration/social Starts an end-user registration session by passing a JWT obtained by an IdP. It returns a challenge that will need to be signed by a passkey and used to perform [Complete End User Registration with Wallets](/api-reference/auth/complete-end-user-registration-with-wallets). #### Authentication No authentication required. #### Required Permissions No authentication required. # Create User Source: https://docs.dfns.co/api-reference/auth/create-user /openapi.yaml post /auth/users Invite a new user in the caller's org. This will create the user and send a registration email to the created User's email, with a registration code, and pointing him to complete his registration on Dfns Dashboard. The user is created without any permissions. If you want the created User to not know about about Dfns, and don't want him to receive the registration email from Dfns, you should rather use the Delegated Registration endpoint. #### Authentication βœ… Organization User (`CustomerEmployee`)\ ❌ Delegated User (`EndUser`)\ ❌ Personal Access Token not allowed\ βœ… Service Account #### Required Permissions `Auth:Users:Create`: Always required. # Create User Action Challenge Source: https://docs.dfns.co/api-reference/auth/create-user-action-challenge /openapi.yaml post /auth/action/init Starts a user action signing session, returning a challenge that will be used to verify the user's intent to perform an action. This is the first step of the [User Action Signing flow](https://docs.dfns.co/api-reference/auth/signing-flows). #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions No permission required. # Create User Action Signature Source: https://docs.dfns.co/api-reference/auth/create-user-action-signature /openapi.yaml post /auth/action Completes the user action signing process and provides a signing token that can be used to verify the user intended to perform the action. This is the first step of the [User Action Signing flow](https://docs.dfns.co/api-reference/auth/signing-flows). The type of credentials used to sign the action is determined by the `kind` field in the nested objects (`firstFactor` and `secondFactor`). Supported credential kinds are: * `Fido2`: User action is signed by a user's signing device using `WebAuthn`. * `Key`: User action is signed by a user's, or token's, private key. * `PasswordProtectedKey`: Login challenge is signed by the decrypted user's private key that was sent during [Create User Action Signature Challenge](https://docs.dfns.co/api-reference/auth/create-user-action-challenge) step. #### Authentication βœ… Organization User (`CustomerEmployee`)\ βœ… Delegated User (`EndUser`)\ βœ… Service Account #### Required Permissions No permission required. # Credentials Source: https://docs.dfns.co/api-reference/auth/credentials API endpoints to create, list, activate, deactivate, and manage user credentials such as passkeys, signing keys, and recovery credentials. User Credentials are used to sign any API call that requires user signature. Most API requests (non-readonly requests mostly) require such a signature. Credentials can be of different kinds (see below), but are essentially all a public/private keypair. The private part is only known and kept by the user. The public key is shared with DFNS, so DFNS can validate the signature produced by the private key. ## Credential kinds * **`Fido2`** (Passkeys / WebAuthn). Recommended for human users. Uses the [WebAuthn standard](https://en.wikipedia.org/wiki/WebAuthn) to create and store passkeys on the user's device. Passkeys are tied to a domain name that must be [whitelisted](/guides/developers/webauthn-configuration#dashboard-configuration) in your DFNS dashboard. * **`Key`**. A raw public/private keypair, primarily for [Service Accounts](/api-reference/auth/service-accounts). You generate and store the keypair yourself. See [Generate a Key Pair](/guides/developers/generate-a-key-pair). * **`PasswordProtectedKey`**. Like a Key credential, but the private key is stored by DFNS in encrypted form. DFNS never has the password. Encryption and decryption must happen on the frontend so you never access the decrypted key. During login and signing, the API returns the `encryptedPrivateKey` for the user to decrypt locally. * **`RecoveryKey`**. Like a Key credential, but designed for account recovery. The user safekeeps a human-readable recovery code. When used, all other credentials are invalidated. See [Implementing end-user recovery](/guides/developers/end-user-recovery). Not all identity types support all credential kinds: | Identity | WebAuthn (Fido2) | Key | | --------------------------- | ---------------- | --- | | User | Yes | Yes | | PAT (Personal Access Token) | No | Yes | | Service Account | No | Yes | ## Redundancy Users can register multiple credentials, and this is recommended. If a user loses access to one credential (e.g. a lost phone), they can still authenticate with another. Register credentials on separate devices (e.g. laptop and a YubiKey) for resilience. ## Credential Signature Flow Most API requests (non-readonly requests mostly) require the signature from a valid Credential owned by the User. The credential signature flow usually looks like: 1. User calls a first endpoint to get a challenge back (some cypher text that needs to be signed) 2. User sign the challenge using a valid credential 3. User calls a second endpoint to submit the signature Different types of challenges that can be requested by a User: * A Registration Challenge (to register the first user credential, when user registers) * A Login Challenge (to login and get an auth token) * A User Action Challenge (required by most non-readonly API calls) * A Credential Challenge (used to create a new Credential) ## Credential Creation Flows There are two possible flows to create a new Credential for a User. The flow you will choose depend on where the User is (which app), and whether he has access to his existing credential from this place. ### Regular flow This flow requires the last call (registration of the new credential) to be signed by an existing valid credential. That means that the user needs to have an existing credential accessible from the place where he's adding a new credential. 1. Call [Create Credential Challenge](/api-reference/auth/create-credential-challenge) to get a "Credential challenge" back. This endpoint does not require a user-action-signature required, so no credential signature involved here. 2. Create a new credential locally, sign the above challenge with it. 3. Call [Create Credential](/api-reference/auth/create-credential) to complete. This endpoint requires a [User Action Flow](/api-reference/auth/signing-flows), so it involves signing first **with an existing valid credential** to get an user action token. ### Create Credential With Code flow This flow requires the first call to be signed by an existing valid credential (creating the code). From then, the last steps can be performed without signature from a valid credential. This flow is useful when you want a user to create a new Credential from an app which doesn't have access to the existing valid credential (since passkeys are tied to the domain name, they cannot be used "cross-domain", eg. a passkey registered on domain `www.app-1.com` cannot be used inside the app `www.app-2.com)` 1. In App 1, call [Create Credential Code](/api-reference/auth/create-credential-code) to get a one-time code. The code will only be valid for 1 minute. This endpoint requires a [User Action Flow](/api-reference/auth/signing-flows), so it involves signing first **with an existing valid credential** to get an user action token. 2. In App 2, call [Create Credential Challenge With Code](/api-reference/auth/create-credential-challenge-with-code) (passing the code from step 1) to get a "Credential challenge" back 3. In App 2, create a new credential locally, sign the above challenge with it. 4. In App 2, call [Create Credential With Code](/api-reference/auth/create-credential-with-code) to complete (passing the code from step 1). This endpoint does not require a user-action-signature required, so no credential signature involved here This [demo video](https://www.loom.com/share/a8b3cbca4b934f659e2e37e676762b87?sid=6aa89bfa-ac59-4c87-897e-79085d916aa0) showcases this flow and how you could implement it in your product.