From 8af9a141dddae91971cf09814b0116d54a6da70c Mon Sep 17 00:00:00 2001 From: Nityam Tripathi <100020368+Nityam573@users.noreply.github.com> Date: Tue, 7 Oct 2025 12:17:57 +0000 Subject: [PATCH 01/15] login using privado --- docs/wallet/login-with-privado.md | 282 ++++++++++++++++++++++++++++++ sidebars.js | 1 + 2 files changed, 283 insertions(+) create mode 100644 docs/wallet/login-with-privado.md diff --git a/docs/wallet/login-with-privado.md b/docs/wallet/login-with-privado.md new file mode 100644 index 00000000..6601b386 --- /dev/null +++ b/docs/wallet/login-with-privado.md @@ -0,0 +1,282 @@ +--- +id: login-with-privado +title: Login Using Privado ID Guide +sidebar_label: Login Using Privado ID +description: Tutorial on how to use Privado ID for login. +keywords: + - docs + - privado id + - login + - issuer + - verifier + - authentication +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +A comprehensive developer guide for implementing basic authentication using Privado ID without zero-knowledge proof requirements. + + +## Overview + +This implementation demonstrates **basic authentication** with Privado ID - verifying user identity through DID (Decentralized Identifier) ownership without requiring additional proofs or credentials. Think of it as "Login with DID" similar to "Login with Google" but decentralized. + +### What This Does ✅ +- Verifies user ownership over a DID +- Provides cryptographic authentication +- Enables web2-like login experience + +### What This Doesn't Do ❌ +- a hassle of collecting your personal data ;) + +## How Basic Authentication Works + +When a user wants to authenticate with Privado ID, here's the complete flow: + +### **1. User Clicks Login** +- User clicks "Login" button +- This triggers a request to your server's `/api/sign-in` endpoint + +### **2. User Forwarded to PrivadoID Wallet** +- User is redirected to their Privado ID web wallet +- Privado ID web wallet prompts to sign in using your crypto wallet + +### **3. Signature Request in Wallet** +- Crypto wallet prompts user to perform a signature request +- User approves the authentication +- Wallet generates a signed JWZ (JSON Web Zero-knowledge) token + +### **4. Callback URL Response** +- After successful signature, the wallet automatically sends a POST request to your callback URL +- Request includes the sessionId and the signed JWZ token in the body + +### **5. Verifier Validation & Successful Login** +- Your server receives the JWZ token in the callback +- Verifier takes the token and validates it against the original auth request: + - Checks JWZ signature matches the user's DID +- Thus, proving his ownership on the DID. + + +## Prerequisites + +### Dependencies + +```bash +npm install @iden3/js-iden3-auth express cors raw-body +``` + +### Required Setup + +1. **Verifier DID**: Your application's decentralized identifier +2. **Keys Directory**: Circuit files for cryptographic verification +3. **Public URL**: For receiving authentication callbacks (use ngrok for development) +4. **State Resolvers**: Blockchain connection for DID validation + + +### 🔑 Keys Directory Setup + +You can find the complete key directory setup [here](https://github.com/0xPolygonID/tutorial-examples/tree/main/verifier-integration) in `keys` folder. + + +## Step-by-Step Implementation + +### 1. Server Configuration +Sets up Express server with required middleware and routes for handling authentication requests and callbacks. + +```javascript +// index.js +const path = require("path"); +const express = require("express"); +const { auth, resolver } = require("@iden3/js-iden3-auth"); +const getRawBody = require("raw-body"); +const cors = require('cors'); + +const app = express(); +const port = 8080; + +// Middleware +app.use(express.static("../static")); +app.use(cors()); + +// Session storage for auth requests +const requestMap = new Map(); + +// Routes +app.get("/api/sign-in", getAuthRequest); +app.post("/api/callback", callback); + +app.listen(port, () => { + console.log(`Server running on port ${port}`); +}); +``` + +💡 **Testing Frontend**: The `../static` directory contains a lightweight frontend for testing the authentication flow. This minimal implementation demonstrates QR code generation, universal link handling, and callback processing - perfect for understanding the complete user journey before building your production frontend. + +### 2. Authentication Request Handler +Generates basic authentication requests with empty scope and stores them with unique session IDs for later verification. + +```javascript +async function getAuthRequest(req, res) { + try { + // Configuration - Update these for your setup + const hostUrl = " Your public URL"; + const callbackURL = "/api/callback"; + const audience = "did:polygonid:polygon:amoy:2qQ68JkRcf3xrHPQPWZei3YeVzHPP58wYNxx2mEouR"; // Your verifier DID + + // Generate unique session + const sessionId = Date.now(); + const uri = `${hostUrl}${callbackURL}?sessionId=${sessionId}`; + + // Create basic auth request (no proofs required) + const request = auth.createAuthorizationRequest( + "Basic Sign In", // Reason for authentication + audience, // Your verifier DID + uri // Callback URL + ); + + // KEY: Remove scope to disable proof requirements + request.body.scope = []; + + // Store for later verification + requestMap.set(`${sessionId}`, request); + + console.log(`Created basic auth request for session: ${sessionId}`); + return res.status(200).json(request); + + } catch (error) { + console.error("Error creating auth request:", error); + return res.status(500).json({ error: "Failed to create auth request" }); + } +} +``` + +💡 **Getting Your Verifier DID**: Sign in to your [Privado ID Wallet](https://wallet.privado.id/) and use the DID displayed there as your verifier DID for simplicity during development. + +## How Does `getAuthRequest` Connect to My Wallet? + +This is where [**Universal Links**](./universal-links.md) come into play! Your frontend takes the auth request returned by `getAuthRequest()` and converts it into a Universal Link that directly opens the user's Privado ID wallet. The wallet automatically processes this request, prompts the user for signature approval, and sends the signed response back to your callback endpoint - creating a seamless authentication experience across mobile and web platforms. + +### Universal Link Structure + +``` +https://wallet.privado.id/#i_m= +``` + +**Components:** +- **Base URL**: `https://wallet.privado.id/` - Privado ID wallet endpoint +- **Fragment**: `#i_m=` - Parameter for auth request +- **Payload**: Base64 encoded JSON auth request + +### 3. Verification Callback Handler +Receives JWZ token as a callback, validates them against stored authentication requests, and confirms user DID ownership. + +```javascript +async function callback(req, res) { + try { + // 1. Extract session and token + const sessionId = req.query.sessionId; + if (!sessionId) { + return res.status(400).json({ error: "Session ID is required" }); + } + + const raw = await getRawBody(req); + const tokenStr = raw.toString().trim(); + if (!tokenStr) { + return res.status(400).json({ error: "Token is required" }); + } + + // 2. Setup blockchain resolvers + const resolvers = { + ["polygon:amoy"]: new resolver.EthStateResolver( + "", + "0x1a4cC30f2aA0377b0c3bc9848766D90cb4404124" + ), + ["privado:main"]: new resolver.EthStateResolver( + "https://rpc-mainnet.privado.id", + "0x3C9acB2205Aa72A05F6D77d708b5Cf85FCa3a896" + ) + }; + + // 3. Retrieve stored auth request + const authRequest = requestMap.get(`${sessionId}`); + if (!authRequest) { + return res.status(400).json({ + error: "Invalid session ID or session expired" + }); + } + + // 4. Initialize verifier + const keyDIR = "../keys"; + const verifier = await auth.Verifier.newVerifier({ + stateResolver: resolvers, + circuitsDir: path.join(__dirname, keyDIR), + ipfsGatewayURL: "https://ipfs.io", + }); + + // 5. Verify authentication + const opts = { + AcceptedStateTransitionDelay: 5 * 60 * 1000, // 5 minutes + }; + + const authResponse = await verifier.fullVerify(tokenStr, authRequest, opts); + + // 6. Clean up and respond + requestMap.delete(`${sessionId}`); + + console.log(`Authentication successful for session: ${sessionId}`); + console.log("User DID:", authResponse.from); + + return res.status(200).json({ + success: true, + message: "Basic authentication successful", + userDID: authResponse.from, + timestamp: new Date().toISOString(), + sessionId: sessionId + }); + + } catch (error) { + console.error("Authentication error:", error); + return res.status(500).json({ + error: "Authentication failed", + details: error.message + }); + } +} +``` + +Congrats!!! You already verify DID ownership. Now to turn this into a full login, on successful callback save a sessionId ↔ DID record in your database, create a session for the browser, and use it to identify the user on later requests!! + +### Testing Steps + +1. **Visit your app:** `http://localhost:8080` +2. **Test universal link:** Click "Login" button +3. **Check console logs:** Monitor authentication flow +4. **Verify response:** Should receive success JSON with userDID + + +### Common Issues + +1. **Invalid DID Format**: Ensure your verifier DID follows the correct format +2. **Network Configuration**: Verify RPC URLs and contract addresses +3. **Circuit Files**: Ensure all required circuit files are present in the circuits directory +4. **CORS Issues**: Configure CORS properly for cross-origin requests + +--- + +## Going Further: 2FA via Google Sign‑In + +With basic DID login in place, you can add two-factor authentication with Google Sign-In without changing the core flow: after verifying the DID, prompt a Google Sign-In and bind the user’s Gmail to their DID (store did ↔ gmail); on future logins, require both the DID check and a fresh Google assertion for that Gmail. This keeps DID as the primary identity, uses Google as the second factor, and lets you leverage Google’s recovery and device safeguards while staying decentralized. + + +## Resources + +### Documentation +- [Privado ID Documentation](https://docs.privado.id/) +- [Verification Library API](https://docs.privado.id/docs/verifier/verification-library/verification-api/) +- [Verifier Integration Examples](https://github.com/0xPolygonID/tutorial-examples) + +--- + +This implementation provides a solid foundation for Privado ID basic authentication. For advanced use cases involving credential verification and zero-knowledge proofs, refer to the official Privado ID documentation and explore the query-based authentication examples. \ No newline at end of file diff --git a/sidebars.js b/sidebars.js index 49b2638f..1792690e 100644 --- a/sidebars.js +++ b/sidebars.js @@ -185,6 +185,7 @@ module.exports = { ] }, + "wallet/login-with-privado", { type: "category", label: "Wallet SDK", From 9da585c4ba11225e3f7887b40bbbd1468f844da6 Mon Sep 17 00:00:00 2001 From: Nityam Tripathi <100020368+Nityam573@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:41:58 +0000 Subject: [PATCH 02/15] fix --- docs/wallet/login-with-privado.md | 115 ++++++++++++++---------------- 1 file changed, 53 insertions(+), 62 deletions(-) diff --git a/docs/wallet/login-with-privado.md b/docs/wallet/login-with-privado.md index 6601b386..0cab2fab 100644 --- a/docs/wallet/login-with-privado.md +++ b/docs/wallet/login-with-privado.md @@ -16,69 +16,59 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import useBaseUrl from '@docusaurus/useBaseUrl'; -A comprehensive developer guide for implementing basic authentication using Privado ID without zero-knowledge proof requirements. - +A hands-on developer guide to integrate Login with Privado ID — a simple, decentralized authentication method using Decentralised Identifiers (DIDs), without any zero-knowledge proofs required. ## Overview -This implementation demonstrates **basic authentication** with Privado ID - verifying user identity through DID (Decentralized Identifier) ownership without requiring additional proofs or credentials. Think of it as "Login with DID" similar to "Login with Google" but decentralized. +Implement **Login with Privado ID** to add a secure, decentralized authentication experience to your application — similar to “Login with Google,” but powered by Decentralized Identifiers (DIDs). + +This guide walks you through setting up **basic authentication** using Privado ID. It verifies user identity through DID ownership + +### Key Capabilities +- **Authenticates DID Ownership**: Authenticates users by cryptographically proving ownership of their DID -### What This Does ✅ -- Verifies user ownership over a DID -- Provides cryptographic authentication -- Enables web2-like login experience +- **Enables Trustless Authentication**: Removes reliance on centralized identity providers. -### What This Doesn't Do ❌ -- a hassle of collecting your personal data ;) +- **Delivers a Familiar Web2 Experience** ## How Basic Authentication Works -When a user wants to authenticate with Privado ID, here's the complete flow: +The Login with Privado ID flow authenticates users by verifying control over their DID. +Below is a high-level breakdown of how the flow works end-to-end: -### **1. User Clicks Login** -- User clicks "Login" button -- This triggers a request to your server's `/api/sign-in` endpoint +- The user clicks “Login with Privado ID” on the app, which triggers a request to the backend(`/api/sign-in` endpoint) to generate a new authentication request for the user -### **2. User Forwarded to PrivadoID Wallet** -- User is redirected to their Privado ID web wallet -- Privado ID web wallet prompts to sign in using your crypto wallet +:::note -### **3. Signature Request in Wallet** -- Crypto wallet prompts user to perform a signature request -- User approves the authentication -- Wallet generates a signed JWZ (JSON Web Zero-knowledge) token +💡 You may also display a QR code that users can scan with the Privado ID Wallet app to start the same flow -### **4. Callback URL Response** -- After successful signature, the wallet automatically sends a POST request to your callback URL -- Request includes the sessionId and the signed JWZ token in the body +::: -### **5. Verifier Validation & Successful Login** -- Your server receives the JWZ token in the callback -- Verifier takes the token and validates it against the original auth request: - - Checks JWZ signature matches the user's DID -- Thus, proving his ownership on the DID. +- The frontend takes the authentication request from the backend, encodes it in Base64, and configures it into a [Universal Link](./universal-links.md). This link opens the Privado ID Web Wallet, prompting the user to sign-in with their crypto wallet +- Once sign-in with crypto wallet is approved by user, the Privado wallet generates a `signed JWZ` (JSON Web Zero-knowledge) token — a verifiable proof of DID ownership. -## Prerequisites +- The wallet then automatically sends a POST request to the backend’s `/api/callback` endpoint containing the `sessionId` and the `signed JWZ` token for verification -### Dependencies +- The backend verifies the signed JWZ token against the stored authentication request using the Privado Verifier -```bash -npm install @iden3/js-iden3-auth express cors raw-body -``` +- Once the JWZ is validated, you can consider the user’s DID as verified and proceed to create or update their record in your database. -### Required Setup +- From here, your application can decide what to do with this verified DID — such as enabling login, granting access, or allowing participation in specific flows like airdrops or allowlists -1. **Verifier DID**: Your application's decentralized identifier -2. **Keys Directory**: Circuit files for cryptographic verification -3. **Public URL**: For receiving authentication callbacks (use ngrok for development) -4. **State Resolvers**: Blockchain connection for DID validation +## Dependencies +```bash +npm install @iden3/js-iden3-auth express cors raw-body +``` -### 🔑 Keys Directory Setup +### Setup -You can find the complete key directory setup [here](https://github.com/0xPolygonID/tutorial-examples/tree/main/verifier-integration) in `keys` folder. +To get started with Login with Privado ID, ensure the following environment requirements are met: +- **Verifier DID**: Your application’s DID used to verify authentication requests +- **Keys Directory**: Contains circuit and verification key files for validation. A sample structure is available in the [verifier-integration](https://github.com/0xPolygonID/tutorial-examples/tree/main/verifier-integration) repository under the `keys/` folder +- **Public URL**: For receiving authentication callbacks (use ngrok for development) ## Step-by-Step Implementation @@ -96,8 +86,7 @@ const cors = require('cors'); const app = express(); const port = 8080; -// Middleware -app.use(express.static("../static")); +app.use(express.static("./static")); app.use(cors()); // Session storage for auth requests @@ -112,7 +101,12 @@ app.listen(port, () => { }); ``` -💡 **Testing Frontend**: The `../static` directory contains a lightweight frontend for testing the authentication flow. This minimal implementation demonstrates QR code generation, universal link handling, and callback processing - perfect for understanding the complete user journey before building your production frontend. +:::info + +💡 **Testing Frontend**: The `./static` directory includes a simple frontend to test the full authentication flow — QR code generation, Universal Link handling, and callback processing. +Once the flow works locally, integrate the same endpoints into your production frontend, update the callback to your live URL, and secure configurations with environment variables and HTTPS. + +::: ### 2. Authentication Request Handler Generates basic authentication requests with empty scope and stores them with unique session IDs for later verification. @@ -154,20 +148,19 @@ async function getAuthRequest(req, res) { 💡 **Getting Your Verifier DID**: Sign in to your [Privado ID Wallet](https://wallet.privado.id/) and use the DID displayed there as your verifier DID for simplicity during development. -## How Does `getAuthRequest` Connect to My Wallet? +## How Does `getAuthRequest` Connect to Privado ID Wallet? -This is where [**Universal Links**](./universal-links.md) come into play! Your frontend takes the auth request returned by `getAuthRequest()` and converts it into a Universal Link that directly opens the user's Privado ID wallet. The wallet automatically processes this request, prompts the user for signature approval, and sends the signed response back to your callback endpoint - creating a seamless authentication experience across mobile and web platforms. +This is where [**Universal Links**](./universal-links.md) come into play! Your frontend takes the auth request returned by `getAuthRequest()`, encodes it in Base64, and embeds it into a Universal Link which in turn redirects the user to Privado ID wallet. The wallet processes the request, prompts the user to sign, and then posts a signed JWZ (JSON Web Zero-knowledge) token to your callback endpoint. That JWZ is what your backend verifies to confirm DID ownership, and thus delivers a seamless login flow across web and mobile. ### Universal Link Structure -``` +```javascript https://wallet.privado.id/#i_m= ``` **Components:** - **Base URL**: `https://wallet.privado.id/` - Privado ID wallet endpoint - **Fragment**: `#i_m=` - Parameter for auth request -- **Payload**: Base64 encoded JSON auth request ### 3. Verification Callback Handler Receives JWZ token as a callback, validates them against stored authentication requests, and confirms user DID ownership. @@ -208,7 +201,7 @@ async function callback(req, res) { } // 4. Initialize verifier - const keyDIR = "../keys"; + const keyDIR = "./keys"; const verifier = await auth.Verifier.newVerifier({ stateResolver: resolvers, circuitsDir: path.join(__dirname, keyDIR), @@ -246,37 +239,35 @@ async function callback(req, res) { } ``` -Congrats!!! You already verify DID ownership. Now to turn this into a full login, on successful callback save a sessionId ↔ DID record in your database, create a session for the browser, and use it to identify the user on later requests!! +You’ve successfully verified DID ownership. + +To turn this into a complete login, store user session details by their DID in your database. The DID acts as a persistent identity, allowing your app to recognize returning users. + +When a user logs in again with the same Privado ID Wallet, they’ll present the same DID, letting your application instantly identify them and deliver the right personalized experience — decentralized, secure, and private. ### Testing Steps 1. **Visit your app:** `http://localhost:8080` 2. **Test universal link:** Click "Login" button -3. **Check console logs:** Monitor authentication flow -4. **Verify response:** Should receive success JSON with userDID - -### Common Issues - -1. **Invalid DID Format**: Ensure your verifier DID follows the correct format -2. **Network Configuration**: Verify RPC URLs and contract addresses -3. **Circuit Files**: Ensure all required circuit files are present in the circuits directory -4. **CORS Issues**: Configure CORS properly for cross-origin requests +You can test the full authentication loop — from generating the auth request to verifying the DID — ensuring your app correctly recognizes verified users --- -## Going Further: 2FA via Google Sign‑In - -With basic DID login in place, you can add two-factor authentication with Google Sign-In without changing the core flow: after verifying the DID, prompt a Google Sign-In and bind the user’s Gmail to their DID (store did ↔ gmail); on future logins, require both the DID check and a fresh Google assertion for that Gmail. This keeps DID as the primary identity, uses Google as the second factor, and lets you leverage Google’s recovery and device safeguards while staying decentralized. +## Going Further: Beyond Basic Login +With **Login with Privado ID**, you’re not just authenticating users — you’re building the foundation for a unified Web3 identity layer. +Once DID-based login is in place, it can power any authentication experience — from crypto wallet sign-ins to Privado credentials, or even Google 2FA — all anchored to a single decentralized identity. ## Resources ### Documentation -- [Privado ID Documentation](https://docs.privado.id/) - [Verification Library API](https://docs.privado.id/docs/verifier/verification-library/verification-api/) - [Verifier Integration Examples](https://github.com/0xPolygonID/tutorial-examples) +### Example Repository +- [Repo](https://github.com/0xPolygonID/tutorial-examples/tree/main/verifier-integration/login-privado) + --- This implementation provides a solid foundation for Privado ID basic authentication. For advanced use cases involving credential verification and zero-knowledge proofs, refer to the official Privado ID documentation and explore the query-based authentication examples. \ No newline at end of file From f357ebab51e96e32a93e66ce72827e114ed13d75 Mon Sep 17 00:00:00 2001 From: Nityam Tripathi <100020368+Nityam573@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:45:18 +0000 Subject: [PATCH 03/15] fix --- docs/wallet/login-with-privado.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/wallet/login-with-privado.md b/docs/wallet/login-with-privado.md index 0cab2fab..4e020d6e 100644 --- a/docs/wallet/login-with-privado.md +++ b/docs/wallet/login-with-privado.md @@ -270,4 +270,4 @@ Once DID-based login is in place, it can power any authentication experience — --- -This implementation provides a solid foundation for Privado ID basic authentication. For advanced use cases involving credential verification and zero-knowledge proofs, refer to the official Privado ID documentation and explore the query-based authentication examples. \ No newline at end of file +This implementation provides a solid foundation for Privado ID basic authentication. For advanced use cases involving credential verification and zero-knowledge proofs, refer to the [query-based authentication](../verifier/verification-library/verifier-set-up.md) example. \ No newline at end of file From e528ec8ff30b69ee584bcc80952421bdc24b2f35 Mon Sep 17 00:00:00 2001 From: Nityam Tripathi <100020368+Nityam573@users.noreply.github.com> Date: Wed, 8 Oct 2025 14:55:24 +0000 Subject: [PATCH 04/15] fix --- docs/wallet/login-with-privado.md | 38 +++++++++++++------------------ 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/docs/wallet/login-with-privado.md b/docs/wallet/login-with-privado.md index 4e020d6e..705e26de 100644 --- a/docs/wallet/login-with-privado.md +++ b/docs/wallet/login-with-privado.md @@ -36,42 +36,37 @@ This guide walks you through setting up **basic authentication** using Privado I The Login with Privado ID flow authenticates users by verifying control over their DID. Below is a high-level breakdown of how the flow works end-to-end: -- The user clicks “Login with Privado ID” on the app, which triggers a request to the backend(`/api/sign-in` endpoint) to generate a new authentication request for the user +1. The user clicks “Login with Privado ID” on the app, which triggers a request to the backend(`/api/sign-in` endpoint) to generate a new authentication request for the user -:::note +:::info -💡 You may also display a QR code that users can scan with the Privado ID Wallet app to start the same flow +You may also display a QR code that users can scan with the Privado ID Wallet app to start the same flow ::: -- The frontend takes the authentication request from the backend, encodes it in Base64, and configures it into a [Universal Link](./universal-links.md). This link opens the Privado ID Web Wallet, prompting the user to sign-in with their crypto wallet +2. The frontend takes the authentication request from the backend, encodes it in Base64, and configures it into a [Universal Link](./universal-links.md). This link opens the Privado ID Web Wallet, prompting the user to sign-in with their crypto wallet -- Once sign-in with crypto wallet is approved by user, the Privado wallet generates a `signed JWZ` (JSON Web Zero-knowledge) token — a verifiable proof of DID ownership. +3. Once sign-in with crypto wallet is approved by user, the Privado wallet generates a `signed JWZ` (JSON Web Zero-knowledge) token — a verifiable proof of DID ownership. -- The wallet then automatically sends a POST request to the backend’s `/api/callback` endpoint containing the `sessionId` and the `signed JWZ` token for verification +4. The wallet then automatically sends a POST request to the backend’s `/api/callback` endpoint containing the `sessionId` and the `signed JWZ` token for verification -- The backend verifies the signed JWZ token against the stored authentication request using the Privado Verifier +5. The backend verifies the signed JWZ token against the stored authentication request using the Privado Verifier -- Once the JWZ is validated, you can consider the user’s DID as verified and proceed to create or update their record in your database. +6. Once the JWZ is validated, you can consider the user’s DID as verified and proceed to create or update their record in your database. -- From here, your application can decide what to do with this verified DID — such as enabling login, granting access, or allowing participation in specific flows like airdrops or allowlists +7. From here, your application can decide what to do with this verified DID — such as enabling login, granting access, or allowing participation in specific flows like airdrops or allowlists -## Dependencies +## Setup ```bash npm install @iden3/js-iden3-auth express cors raw-body ``` -### Setup - To get started with Login with Privado ID, ensure the following environment requirements are met: -- **Verifier DID**: Your application’s DID used to verify authentication requests - **Keys Directory**: Contains circuit and verification key files for validation. A sample structure is available in the [verifier-integration](https://github.com/0xPolygonID/tutorial-examples/tree/main/verifier-integration) repository under the `keys/` folder - **Public URL**: For receiving authentication callbacks (use ngrok for development) -## Step-by-Step Implementation - ### 1. Server Configuration Sets up Express server with required middleware and routes for handling authentication requests and callbacks. @@ -103,7 +98,7 @@ app.listen(port, () => { :::info -💡 **Testing Frontend**: The `./static` directory includes a simple frontend to test the full authentication flow — QR code generation, Universal Link handling, and callback processing. +**Testing Frontend**: The `./static` directory includes a simple frontend to test the full authentication flow — QR code generation, Universal Link handling, and callback processing. Once the flow works locally, integrate the same endpoints into your production frontend, update the callback to your live URL, and secure configurations with environment variables and HTTPS. ::: @@ -130,7 +125,6 @@ async function getAuthRequest(req, res) { uri // Callback URL ); - // KEY: Remove scope to disable proof requirements request.body.scope = []; // Store for later verification @@ -146,7 +140,11 @@ async function getAuthRequest(req, res) { } ``` -💡 **Getting Your Verifier DID**: Sign in to your [Privado ID Wallet](https://wallet.privado.id/) and use the DID displayed there as your verifier DID for simplicity during development. +:::info + +**Getting Your Verifier DID**: Sign in to your [Privado ID Wallet](https://wallet.privado.id/) and use the DID displayed there as your verifier DID for simplicity during development. + +::: ## How Does `getAuthRequest` Connect to Privado ID Wallet? @@ -261,10 +259,6 @@ Once DID-based login is in place, it can power any authentication experience — ## Resources -### Documentation -- [Verification Library API](https://docs.privado.id/docs/verifier/verification-library/verification-api/) -- [Verifier Integration Examples](https://github.com/0xPolygonID/tutorial-examples) - ### Example Repository - [Repo](https://github.com/0xPolygonID/tutorial-examples/tree/main/verifier-integration/login-privado) From f50702e1cd47f94af6f7556381200ff40cb14ffd Mon Sep 17 00:00:00 2001 From: Nityam Tripathi <100020368+Nityam573@users.noreply.github.com> Date: Wed, 8 Oct 2025 18:46:20 +0000 Subject: [PATCH 05/15] fix --- docs/wallet/login-with-privado.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/wallet/login-with-privado.md b/docs/wallet/login-with-privado.md index 705e26de..9c576967 100644 --- a/docs/wallet/login-with-privado.md +++ b/docs/wallet/login-with-privado.md @@ -219,13 +219,7 @@ async function callback(req, res) { console.log(`Authentication successful for session: ${sessionId}`); console.log("User DID:", authResponse.from); - return res.status(200).json({ - success: true, - message: "Basic authentication successful", - userDID: authResponse.from, - timestamp: new Date().toISOString(), - sessionId: sessionId - }); + return res.status(200).set("Content-Type", "application/json").send(authResponse); } catch (error) { console.error("Authentication error:", error); From 24b73c877b9f3c622eb7cc815404a3aa1df15436 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Thu, 9 Oct 2025 06:46:27 -0300 Subject: [PATCH 06/15] Upgrade ECS deploy action to version 2 --- .github/workflows/deployment_new_aws_account.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deployment_new_aws_account.yml b/.github/workflows/deployment_new_aws_account.yml index 1ca578ab..ea2c4f4b 100644 --- a/.github/workflows/deployment_new_aws_account.yml +++ b/.github/workflows/deployment_new_aws_account.yml @@ -72,9 +72,9 @@ jobs: image: ${{ steps.build-image.outputs.image }} - name: Deploy Amazon ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: task-definition: ${{ steps.task-def.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} cluster: ${{ vars.ECS_CLUSTER }} - wait-for-service-stability: true \ No newline at end of file + wait-for-service-stability: true From 7773f491443c91c3817730773437af5af4e59f98 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Thu, 9 Oct 2025 07:46:56 -0300 Subject: [PATCH 07/15] Upgrade ECS task definition action and add debug step Updated the Amazon ECS render task definition action to v2 and added a debug step to output the rendered task definition. --- .github/workflows/deployment_new_aws_account.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deployment_new_aws_account.yml b/.github/workflows/deployment_new_aws_account.yml index ea2c4f4b..fc027b5c 100644 --- a/.github/workflows/deployment_new_aws_account.yml +++ b/.github/workflows/deployment_new_aws_account.yml @@ -65,12 +65,19 @@ jobs: - name: Fill in the new image ID in the Amazon ECS task definition id: task-def - uses: aws-actions/amazon-ecs-render-task-definition@v1 + uses: aws-actions/amazon-ecs-render-task-definition@v2 with: task-definition: ${{ vars.ECS_TASK_DEFINITION }} container-name: ${{ vars.CONTAINER_NAME }} image: ${{ steps.build-image.outputs.image }} + - name: Debug rendered task def + run: | + echo "Rendered file: ${{ steps.task-def.outputs.task-definition }}" + cat "${{ steps.task-def.outputs.task-definition }}" + echo "Container names:" + cat "${{ steps.task-def.outputs.task-definition }}" | jq -r '.containerDefinitions[].name' + - name: Deploy Amazon ECS task definition uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: From efb8c706683700d0c79e434e5d41821f8294adde Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Thu, 9 Oct 2025 07:48:18 -0300 Subject: [PATCH 08/15] Update ECS task definition action to version 1 --- .github/workflows/deployment_new_aws_account.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployment_new_aws_account.yml b/.github/workflows/deployment_new_aws_account.yml index fc027b5c..eaf48b57 100644 --- a/.github/workflows/deployment_new_aws_account.yml +++ b/.github/workflows/deployment_new_aws_account.yml @@ -65,7 +65,7 @@ jobs: - name: Fill in the new image ID in the Amazon ECS task definition id: task-def - uses: aws-actions/amazon-ecs-render-task-definition@v2 + uses: aws-actions/amazon-ecs-render-task-definition@v1 with: task-definition: ${{ vars.ECS_TASK_DEFINITION }} container-name: ${{ vars.CONTAINER_NAME }} From dbed394f6df464edf2bb67ca82e63b107de482e7 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Thu, 9 Oct 2025 08:19:56 -0300 Subject: [PATCH 09/15] Downgrade ECS deploy action to version 1 --- .github/workflows/deployment_new_aws_account.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployment_new_aws_account.yml b/.github/workflows/deployment_new_aws_account.yml index eaf48b57..d369d597 100644 --- a/.github/workflows/deployment_new_aws_account.yml +++ b/.github/workflows/deployment_new_aws_account.yml @@ -79,7 +79,7 @@ jobs: cat "${{ steps.task-def.outputs.task-definition }}" | jq -r '.containerDefinitions[].name' - name: Deploy Amazon ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@v2 + uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.task-def.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} From 4dccf97f54c8be0baaa66a79f11b835f7e5c95a5 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Thu, 9 Oct 2025 08:31:29 -0300 Subject: [PATCH 10/15] Upgrade ECS deploy action to version 2 --- .github/workflows/deployment_new_aws_account.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployment_new_aws_account.yml b/.github/workflows/deployment_new_aws_account.yml index d369d597..eaf48b57 100644 --- a/.github/workflows/deployment_new_aws_account.yml +++ b/.github/workflows/deployment_new_aws_account.yml @@ -79,7 +79,7 @@ jobs: cat "${{ steps.task-def.outputs.task-definition }}" | jq -r '.containerDefinitions[].name' - name: Deploy Amazon ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: task-definition: ${{ steps.task-def.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} From d4ae85f2a800e513ea7a2d0e3fcd92a60d267b6c Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Thu, 9 Oct 2025 08:53:34 -0300 Subject: [PATCH 11/15] Add container name to AWS deployment workflow --- .github/workflows/deployment_new_aws_account.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deployment_new_aws_account.yml b/.github/workflows/deployment_new_aws_account.yml index eaf48b57..d0a71996 100644 --- a/.github/workflows/deployment_new_aws_account.yml +++ b/.github/workflows/deployment_new_aws_account.yml @@ -84,4 +84,5 @@ jobs: task-definition: ${{ steps.task-def.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} cluster: ${{ vars.ECS_CLUSTER }} + container-name: ${{ vars.CONTAINER_NAME }} wait-for-service-stability: true From e1e06089994ccc9c3a471d56f957d050cbe76f92 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Fri, 10 Oct 2025 09:36:54 -0300 Subject: [PATCH 12/15] Remove container-name from deployment workflow --- .github/workflows/deployment_new_aws_account.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deployment_new_aws_account.yml b/.github/workflows/deployment_new_aws_account.yml index d0a71996..eaf48b57 100644 --- a/.github/workflows/deployment_new_aws_account.yml +++ b/.github/workflows/deployment_new_aws_account.yml @@ -84,5 +84,4 @@ jobs: task-definition: ${{ steps.task-def.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} cluster: ${{ vars.ECS_CLUSTER }} - container-name: ${{ vars.CONTAINER_NAME }} wait-for-service-stability: true From 58a96cd6dc2f40b8632401e8076ddb5aa0886371 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Fri, 10 Oct 2025 10:27:15 -0300 Subject: [PATCH 13/15] Rename ECS service from 'devs-staging' to 'devs-ecs-service' --- staging-taskdef.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/staging-taskdef.json b/staging-taskdef.json index 1c7c1adb..56d48cde 100644 --- a/staging-taskdef.json +++ b/staging-taskdef.json @@ -44,7 +44,7 @@ "dockerLabels": null, "systemControls": null, "privileged": null, - "name": "devs-staging", + "name": "devs-ecs-service", "repositoryCredentials": { "credentialsParameter": "" } From 24fe10ce04f39bc065cb8a3f157fd35da8eb2049 Mon Sep 17 00:00:00 2001 From: Martin Saporiti Date: Fri, 10 Oct 2025 10:31:42 -0300 Subject: [PATCH 14/15] Rename tooling-dev-devs-app to devs-ecs-service --- develop-taskdef.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-taskdef.json b/develop-taskdef.json index a3467a9e..9125d645 100644 --- a/develop-taskdef.json +++ b/develop-taskdef.json @@ -29,7 +29,7 @@ } }, { - "name": "tooling-dev-devs-app", + "name": "devs-ecs-service", "image": "654654630007.dkr.ecr.eu-west-1.amazonaws.com/devs-ecr", "cpu": 0, "portMappings": [ From ed7eb6e4107ff8bf762c5da93a90e07425cddfda Mon Sep 17 00:00:00 2001 From: Nityam Tripathi <100020368+Nityam573@users.noreply.github.com> Date: Wed, 26 Nov 2025 14:30:53 +0000 Subject: [PATCH 15/15] fix-login-docs --- docs/wallet/login-with-privado.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/wallet/login-with-privado.md b/docs/wallet/login-with-privado.md index 9c576967..56c07c54 100644 --- a/docs/wallet/login-with-privado.md +++ b/docs/wallet/login-with-privado.md @@ -16,11 +16,12 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import useBaseUrl from '@docusaurus/useBaseUrl'; -A hands-on developer guide to integrate Login with Privado ID — a simple, decentralized authentication method using Decentralised Identifiers (DIDs), without any zero-knowledge proofs required. +Enable decentralized, privacy-preserving authentication in your application using Privado ID. This integration lets users authenticate with their Decentralized Identifiers (DIDs), providing a secure, trustless login flow that preserves the familiar simplicity of Web2 sign-in experiences. ## Overview -Implement **Login with Privado ID** to add a secure, decentralized authentication experience to your application — similar to “Login with Google,” but powered by Decentralized Identifiers (DIDs). +Privado ID allows your users to sign in using their DID profile — a self-sovereign identity they fully control. +Think of it as “Login with Google,” but decentralized and trustless, privacy-preserving, and self-sovereign. This guide walks you through setting up **basic authentication** using Privado ID. It verifies user identity through DID ownership @@ -33,7 +34,7 @@ This guide walks you through setting up **basic authentication** using Privado I ## How Basic Authentication Works -The Login with Privado ID flow authenticates users by verifying control over their DID. +The Login with Privado ID flow establishes the user’s identity by validating DID ownership. Below is a high-level breakdown of how the flow works end-to-end: 1. The user clicks “Login with Privado ID” on the app, which triggers a request to the backend(`/api/sign-in` endpoint) to generate a new authentication request for the user @@ -230,8 +231,7 @@ async function callback(req, res) { } } ``` - -You’ve successfully verified DID ownership. +Once the JWZ token validates, You’ve successfully verified DID ownership. To turn this into a complete login, store user session details by their DID in your database. The DID acts as a persistent identity, allowing your app to recognize returning users.