Skip to content

Commit 90b3b21

Browse files
committed
remove pub key refrences
1 parent 62563d8 commit 90b3b21

1 file changed

Lines changed: 66 additions & 94 deletions

File tree

docs.md

Lines changed: 66 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -343,42 +343,39 @@ Before integrating Base Verify, you need:
343343
2. **A mini app** - Your app should run in Coinbase Wallet or Base ecosystem
344344
3. **Wallet integration** - Users must be able to connect and sign messages
345345

346-
### Key Types
346+
### API Keys
347347

348-
You'll receive two types of keys:
348+
You'll receive a **Secret Key** from the Base Verify team.
349349

350-
**Publisher Key** (Public)
351-
- Safe to expose in client-side code
352-
- Used for client-to-API calls
353-
- Requires origin validation (your app domain must be allowlisted)
354-
- Format: `pub_...`
355-
356-
**Secret Key** (Private)
357-
- NEVER expose to clients
358-
- Used only on your backend server
359-
- For privileged operations (verification checks, token generation)
350+
**Secret Key:**
351+
- **NEVER expose to clients or frontend code**
352+
- Must only be used on your backend server
353+
- Used for all API calls to Base Verify
360354
- Format: `sec_...`
361355

356+
**Security Warning:** If you accidentally expose your secret key in frontend code, browser dev tools, or version control, contact the Base Verify team immediately to rotate it.
357+
362358
### Registering Your App
363359

364-
When you receive your keys, you'll also need to register:
360+
When you receive your key, you'll also need to register:
365361

366362
1. **Redirect URIs** - Where users return after verification (e.g., `https://yourapp.com`)
367-
2. **Allowed Origins** - Domains that can make client-side API calls (if using publisher key)
368-
3. **App Name** - How your app appears in the Base Verify flow
363+
2. **App Name** - How your app appears in the Base Verify flow
369364

370365
Contact the Base Verify team to register these settings.
371366

372367
---
373368

374369
## Integration Steps
375370

371+
> **Security Warning:** Your Base Verify secret key must NEVER be exposed in frontend code, browser console, or version control. All Base Verify API calls must go through your backend server. If your key is compromised, contact the Base Verify team immediately.
372+
376373
The integration involves several components working together:
377374

378-
1. **SIWE Message Generation** - Create signed messages proving wallet ownership
379-
2. **Verification Check** - Call Base Verify API to check status
380-
3. **Redirect Handling** - Send users to Base Verify when needed
381-
4. **Token Storage** - Store verification tokens to prevent reuse
375+
1. **SIWE Message Generation** (Frontend) - Create signed messages proving wallet ownership
376+
2. **Verification Check** (Backend) - Call Base Verify API to check status
377+
3. **Redirect Handling** (Frontend) - Send users to Base Verify when needed
378+
4. **Token Storage** (Backend) - Store verification tokens to prevent reuse
382379

383380
Let's walk through each component:
384381

@@ -395,34 +392,21 @@ Create `lib/config.ts`:
395392
```ts
396393
export const config = {
397394
appUrl: 'https://your-app.com',
398-
baseVerifySecretKey: process.env.BASE_VERIFY_SECRET_KEY,
399-
baseVerifyPublisherKey: process.env.BASE_VERIFY_PUBLISHER_KEY,
395+
baseVerifySecretKey: process.env.BASE_VERIFY_SECRET_KEY, // Backend only!
400396
baseVerifyApiUrl: 'https://verify.base.dev/v1',
401397
baseVerifyMiniAppUrl: 'https://verify.base.dev',
402398
}
403399
```
404400

405-
Create `.env.local`:
401+
Create `.env.local` (backend):
406402

407403
```shell
408404
BASE_VERIFY_SECRET_KEY=your_secret_key_here
409-
BASE_VERIFY_PUBLISHER_KEY=your_publisher_key_here
410405
```
411406

412-
Contact [rahul.patni@coinbase.com](mailto:rahul.patni@coinbase.com) to get your secret key and publisher key.
413-
414-
**Key Types:**
415-
416-
You will be provided both a **publisher key** or a **secret key**.
407+
**Important:** Never include your secret key in frontend code or environment variables that are exposed to the browser (like `NEXT_PUBLIC_*` vars).
417408

418-
- **Publisher Key**
419-
- Public identifier, safe to expose in client-side code
420-
- Used to identify your app
421-
- Can be included in frontend bundles
422-
423-
- **Secret Key**
424-
- Private credential, never expose to clients
425-
- Used only on the server for privileged operations (auth, writes, webhooks)
409+
Contact [rahul.patni@coinbase.com](mailto:rahul.patni@coinbase.com) to get your secret key.
426410

427411
### Step 2: Create SIWE Signature Generator (Frontend)
428412

@@ -473,7 +457,13 @@ export async function generateSignature(
473457

474458
**Purpose:** Check if the user has the required verification by calling Base Verify API.
475459

476-
**Runs on:** Can run on frontend (with publisher key) or backend (with secret key, recommended)
460+
**Runs on:** Backend only (secret key must not be exposed to frontend)
461+
462+
**Flow:**
463+
1. Frontend generates SIWE message and gets user signature
464+
2. Frontend sends signature to YOUR backend
465+
3. Your backend calls Base Verify API with secret key
466+
4. Your backend returns result to frontend
477467

478468
**Frontend code:**
479469

@@ -492,40 +482,57 @@ async function checkVerification(address: string) {
492482
address
493483
)
494484

495-
// Check with backend
496-
const response = await fetch(`${config.baseVerifyApiUrl}/base_verify_token`, {
485+
// Send to YOUR backend (not directly to Base Verify)
486+
const response = await fetch('/api/check-verification', {
497487
method: 'POST',
498488
headers: {
499489
'Content-Type': 'application/json',
500-
'Authorization': `Bearer ${config.baseVerifySecretKey}`,
501490
},
502491
body: JSON.stringify({
503492
signature: signature.signature,
504493
message: signature.message,
494+
address: address
505495
})
506496
})
507497

498+
const data = await response.json();
499+
return data; // Your backend returns the result
500+
}
501+
```
502+
503+
**Backend code (YOUR API endpoint):**
504+
505+
```ts
506+
// pages/api/check-verification.ts
507+
export default async function handler(req, res) {
508+
const { signature, message, address } = req.body;
509+
510+
// Call Base Verify with YOUR secret key
511+
const response = await fetch('https://verify.base.dev/v1/base_verify_token', {
512+
method: 'POST',
513+
headers: {
514+
'Content-Type': 'application/json',
515+
'Authorization': `Bearer ${process.env.BASE_VERIFY_SECRET_KEY}`, // Secret key stays on backend
516+
},
517+
body: JSON.stringify({
518+
signature: signature,
519+
message: message,
520+
})
521+
});
522+
508523
if (response.ok) {
509-
return {
510-
verified: true,
511-
data: await response.json()
512-
}
524+
const data = await response.json();
525+
return res.status(200).json({ verified: true, token: data.token });
513526
} else if (response.status === 404) {
514-
return {
515-
verified: false,
516-
message: 'Verification not found. Redirecting to mini app...'
517-
}
527+
return res.status(404).json({ verified: false, needsVerification: true });
518528
} else if (response.status === 400) {
519529
const data = await response.json();
520530
if (data.message === 'verification_traits_not_satisfied') {
521-
return {
522-
verified: false,
523-
message: 'User does not meet trait requirements'
524-
}
531+
return res.status(400).json({ verified: false, traitsNotMet: true });
525532
}
526533
}
527534

528-
throw new Error('Verification check failed')
535+
return res.status(500).json({ error: 'Verification check failed' });
529536
}
530537
```
531538

@@ -561,7 +568,9 @@ After verification, user returns to your `redirect_uri` with `?success=true`. Ch
561568

562569
Check if a wallet has a specific verification and retrieve the verification token.
563570

564-
**Authentication:** Requires `Authorization: Bearer {SECRET_KEY}` or `Authorization: Bearer {PUBLISHER_KEY}`
571+
**Authentication:** Requires `Authorization: Bearer {SECRET_KEY}`
572+
573+
**Important:** This endpoint must only be called from your backend. Never expose your secret key in frontend code.
565574

566575
**Request:**
567576

@@ -810,7 +819,7 @@ The interactive examples let you test real API calls to Base Verify:
810819
- Test your own verification status
811820
- Debug trait requirements before implementing
812821

813-
**Note:** These examples use a publisher key (safe for client-side), so they work directly from your browser.
822+
**Note:** These examples call Base Verify API directly from your browser for demo purposes. In production, you should proxy all Base Verify API calls through your backend to keep your secret key secure.
814823

815824
---
816825

@@ -1054,44 +1063,20 @@ Every API call requires a valid SIWE signature from the wallet owner. This preve
10541063
- Third parties checking if a wallet is verified
10551064
- Enumeration attacks
10561065

1057-
**2. Origin Validation**
1058-
1059-
Publisher keys (client-side) are locked to specific origins:
1060-
- Only your registered domains can use your publisher key
1061-
- Prevents key theft and misuse
1062-
- Enforced at the API level
1063-
1064-
**3. OAuth Token Security**
1066+
**2. OAuth Token Security**
10651067

10661068
- OAuth access tokens are encrypted at rest
10671069
- Never exposed to your application
10681070
- Used only by Base Verify to refresh provider data
10691071
- Can be revoked by user at any time
10701072

1071-
**4. User Control**
1073+
**3. User Control**
10721074

10731075
Users can delete their verifications at any time:
10741076
- Removes all stored provider data
10751077
- Invalidates future token generation
10761078
- Your app's stored tokens become meaningless (user can't re-verify with same account)
10771079

1078-
### Rate Limits
1079-
1080-
To prevent abuse, Base Verify enforces rate limits:
1081-
1082-
| Endpoint | Rate Limit | Per |
1083-
| :---- | :---- | :---- |
1084-
| `/v1/base_verify_token` | 100 requests | per minute per API key |
1085-
| `/v1/verification_url` | 50 requests | per minute per API key |
1086-
| `/v1/verifications` | 100 requests | per minute per API key |
1087-
1088-
If you exceed rate limits, you'll receive a `429 Too Many Requests` response.
1089-
1090-
**Best Practices:**
1091-
- Cache verification results client-side (for the session)
1092-
- Don't check verification on every page load
1093-
- Implement exponential backoff on retries
1094-
10951080
### OAuth Security Model
10961081

10971082
**How Base Verify validates provider accounts:**
@@ -1105,19 +1090,6 @@ If you exceed rate limits, you'll receive a `429 Too Many Requests` response.
11051090

11061091
**Your app never handles OAuth tokens or redirects.** This is all handled within the Base Verify Mini App.
11071092

1108-
### Compliance
1109-
1110-
- **GDPR**: Users can request deletion of their verification data
1111-
- **CCPA**: Users have right to know what data is stored and can delete it
1112-
- **Data Minimization**: Only essential provider data is stored
1113-
1114-
### Reporting Security Issues
1115-
1116-
If you discover a security vulnerability, please email:
1117-
**security@base.org**
1118-
1119-
Do not file public issues for security concerns.
1120-
11211093
---
11221094

11231095
## Try Base Verify

0 commit comments

Comments
 (0)