How Authentication Works with PKPs
Learn about how different authentication methods work with Programmable Key Pairs.
Intro
The purpose of this guide is to introduce how authentication works with Programmable Key Pairs (PKPs). You can find this in our developer docs under Authentication Helpers. We will start by introducing how PKPs and Lit Actions work at a high level and the types of use cases they enable. We will then explore the types of auth methods that are currently supported, and the steps necessary to configure them.
An auth method refers to the specific credential (i.e a wallet address, Google oAuth, or Discord account) that is programmatically tied to the PKP and used to control the underlying key-pair. It is the method that is authorized to sign with the PKP.
By the end of this guide, you should have a clear understanding of how auth methods work with PKPs and how they can be used to support seamless onboarding experiences for non crypto-native users.
Without further ado, let’s dive in.
Understanding PKPs and Lit Actions
Smart contracts are powerful tools, but they are typically limited to the blockchain on which they are deployed. To connect different blockchain ecosystems, specialized solutions such as oracles and bridges must be created.
What if smart contracts had their own unique public and private key pairs, similar to those of a wallet? And what if they were able to make arbitrary HTTP requests and utilize the data in their computations? This would enable smart contracts to read and write data from any HTTP endpoint, blockchain, state machine, or decentralized storage system.
At Lit, we are working to build the tools to help realize this vision. We call our smart contracts Lit Actions, which are immutable JavaScript programs stored on IPFS. The key-pairs they can use are referred to as Programmable Key Pairs, which are threshold ECDSA keys generated collectively by the Lit network.
Together, these features can be harnessed to seamlessly read and write data across previously isolated platforms and ecosystems.
Minting a PKP
Each PKP is generated collectively by the Lit network in a process called Distributed Key Generation (DKG) whereby each node only holds a share of the underlying private key (a key-share) and the complete private key never exists in its entirety.
In order to control this distributed key-pair, you must mint it in the form of an ERC-721 NFT. PKPs can be minted on the official Lit Explorer.
The NFT stands as the “symbol” or method for controlling the distributed key custodied by the Lit network. This means that only the wallet address or smart contract holding the PKP NFT can authorize how it is used for signing. We refer to the contract or wallet address as the root auth method.
Working with Additional Auth Methods
Again, when we say “auth”, we are referring to the particular method that has permission to sign using a PKP. Above, we discussed how the root auth method is the contract or wallet that holds the PKP NFT. This root method can be used to support additional forms of authentication that do not require ownership of a web3 wallet, such as a WebAuthn signature or an oauth token generated by a service like Discord or Google. You can see an example of these methods being implemented here.
These additional methods can be configured using the PKPHelper.sol contract, which allows you to mint a PKP and assign an auth method, all in one transaction. This allows the PKP owner to grant permissions to additional wallet addresses, Lit Actions, or auth methods (like Google OAuth) to sign using their distributed key. The full list of supported auth methods can be found within PKPPermissions.sol.
When a particular user attempts to sign a transaction using a PKP, the auth method they are using will be checked against the smart contract to ensure that they are in fact “authorized”.
Owning a PKP
What if I want to use a PKP but I don’t have a web3 wallet? (for example, using Google Oauth: https://spark.litprotocol.com/wallet-abstraction-with-google-oauth/) — where is that PKP stored, or who actually owns it?
Again, it is important to emphasize that no one ever “owns” the private key of a PKP, as it is stored collectively by every node in the Lit network. If there are 10 nodes, each node will hold 1/10th of the key and at least 6 nodes (two-thirds) will need to provision their share to form the complete signature.
Ownership in the sense of PKPs instead refers to the party or method that is authorized to combine the shares, as explained above. In the case that a user doesn’t own a wallet, there are a few different options available.
Sending the PKP to itself:
If your users don’t have a wallet (and so no contract is there to act as the root auth), you can send the PKP to itself. This enables the PKP in itself to become the root auth method and permission additional functionality. Since the PKP can produce a signature, and since now it’s authorized to sign, you can use it to add additional methods of authentication.
This can be done using the PKPHelper.sol smart contract functions, which can be called on behalf of your users to setup. This is also the only spot where you will need gas, as a transaction is being posted to chain.
When a PKP is sent to itself, a Lit Action is used to configure rules surrounding how additional methods should be added / allowed for auth (for example, “anyone that possesses this JWT can sign with this PKP”).
Burning the PKP:
Another option is burning the PKP. Note that this means no additional auth methods can be added down the line, and should be used with caution.
Auth Sigs vs. Auth Methods
PKP auth methods are not to be confused with auth sigs, which are required to communicate with the nodes in the Lit network. An auth sig is always required when making a request to Lit, whether it be decrypting some piece of content or sending a transaction with a PKP.
You can use any EIP 4361 compliant signature (Sign in with Ethereum) for the AuthSig, but you must put the signature into the AuthSig data structure format (documented here). You do not need to use the Lit JS SDK to obtain the signature as long as it's EIP 4361 compliant and in the AuthSig data structure format.
Creating An Auth Sig Without a Wallet
In the case that a user doesn’t own a wallet (and therefore cannot produce a valid AuthSig), they can present their alternative auth method to the Lit SDK which will convert it into a “compliant” AuthSig. This is documented in our docs and this example project. The flow is as follows:
- Present a PKP public key and an auth token from an authorized auth method (like a Google OAuth JWT), as well as a session public key for a local key-pair that is generated and stored locally.
- The PKP is used to sign a SIWE signature which authorizes the session key-pair going forward.
- The Lit SDK will use the session key to sign future requests. So instead of signing the session key-pair with a wallet, you can sign it using the PKP by communicating with the Lit nodes and presenting proof that you are authorized.
You can read more about AuthSigs in our docs: https://developer.litprotocol.com/sdk/explanation/walletsigs/authsig/
Conclusion
Hopefully now you have a better idea of how auth methods can be configured and managed for PKPs. For additional guidance, check out the appropriate section in the Lit docs.
For a more in-depth exploration of PKPs and Lit Actions, check out this starter guide on our blog. If you’re interested in contributing to the Lit community, check out our Request for Ecosystem Proposals and Grants program.
As always, you can send us a message on Discord with any additional questions, concerns, or difficulties faced when pursuing an integration.
Resources
💻 Developer Documentation: https://developer.litprotocol.com/
👾 Discord: https://litgateway.com/discord
🧑💻 GitHub: https://github.com/LIT-Protocol
🕊 Twitter: https://twitter.com/LitProtocol
🖥 Website: https://litprotocol.com/