Skip to main content

Server-to-Server Authentication

The api_secret auth method is designed for server-to-server integrations where your backend controls the authentication flow. Instead of relying on a third-party auth provider, your backend authenticates directly with the Privacy Boost API using a client_id and client_secret pair — similar to OAuth 2.0 client credentials. This is the right choice when:
  • Your backend already manages user authentication and you don’t use a third-party auth provider
  • You need programmatic access (scripts, bots, automated systems)
  • You want full control over who can authenticate without depending on an external JWKS endpoint

How It Works

API Secret Authentication Flow

Setup

1. Get API Credentials

Contact the Privacy Boost team to configure your app with the api_secret auth method. You’ll receive:
  • App ID — Your application identifier (e.g., app_abc123xyz)
  • Client ID — A unique identifier for your credentials (e.g., pb_cred_abc123xyz...)
  • Client Secret — A secret key for authenticating requests
Store your client_secret securely. It should never be exposed in client-side code, committed to version control, or logged. Use environment variables or a secrets manager.

2. Store Credentials Securely

# Environment variables (development)
export PB_CLIENT_ID="pb_cred_abc123xyz..."
export PB_CLIENT_SECRET="your-secret-here"

# Or use a secrets manager in production (AWS Secrets Manager, HashiCorp Vault, etc.)

Client-Side Integration

Implement a Token Provider

Your token provider routes the SDK’s login payload through your backend:
const tokenProvider = async (loginPayload: any) => {
  const res = await fetch('https://your-backend.com/api/privacy-boost/auth', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${yourSessionToken}`, // Your own auth
    },
    body: JSON.stringify(loginPayload),
  });

  if (!res.ok) throw new Error('Auth failed');
  return await res.json(); // { token, expiresIn }
};

await sdk.auth.authenticate(adapter, {
  type: 'walletDerived',
  tokenProvider,
});

Backend Endpoint

Your backend endpoint receives the SDK’s login payload, adds your API credentials, and forwards to Privacy Boost:
// Express.js example
app.post('/api/privacy-boost/auth', async (req, res) => {
  // 1. Verify your own user auth (session, JWT, etc.)
  const user = await verifyYourAuth(req.headers.authorization);
  if (!user) return res.status(401).json({ error: 'Unauthorized' });

  // 2. Forward to Privacy Boost with API credentials
  const pbResponse = await fetch(
    'https://test-api.privacy-boost.sunnyside.io/indexer/auth/token',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        ...req.body,                          // SDK's login payload (mpk, viewauth_signature, nonce, etc.)
        client_id: process.env.PB_CLIENT_ID,  // Your API credential ID
        client_secret: process.env.PB_CLIENT_SECRET, // Your API secret
      }),
    }
  );

  if (!pbResponse.ok) {
    const err = await pbResponse.json();
    return res.status(pbResponse.status).json(err);
  }

  const data = await pbResponse.json();
  res.json({
    token: data.access_token,
    expiresIn: data.expires_in,
  });
});
# FastAPI example
@app.post("/api/privacy-boost/auth")
async def privacy_boost_auth(request: Request):
    # 1. Verify your own user auth
    user = await verify_your_auth(request.headers.get("authorization"))
    if not user:
        raise HTTPException(status_code=401)

    # 2. Forward to Privacy Boost with API credentials
    payload = await request.json()
    payload["client_id"] = os.environ["PB_CLIENT_ID"]
    payload["client_secret"] = os.environ["PB_CLIENT_SECRET"]

    async with httpx.AsyncClient() as client:
        pb_response = await client.post(
            "https://test-api.privacy-boost.sunnyside.io/indexer/auth/token",
            json=payload,
        )

    data = pb_response.json()
    return {"token": data["access_token"], "expiresIn": data["expires_in"]}

Credential Management

Rotation

API credentials can be rotated without downtime:
  1. Request a new credential from the Privacy Boost team
  2. Update your backend to use the new client_id and client_secret
  3. Revoke the old credential

Expiry

Credentials can optionally have an expiry date. If your credential expires, requests will fail with invalid_credentials. Request a new credential before the current one expires.

Security Best Practices

  1. Never expose credentials in client-side code. The client_id and client_secret must only exist on your backend.
  2. Use environment variables or a secrets manager. Don’t hardcode credentials.
  3. Rotate credentials periodically. Treat them like passwords.
  4. Authenticate your own users first. Your backend endpoint should verify the caller’s identity (session token, JWT, etc.) before forwarding to Privacy Boost. Otherwise, anyone who discovers your endpoint can authenticate.
  5. Use HTTPS only. All communication between your backend and Privacy Boost must be over HTTPS.

Next Steps

Continue with setup: Or explore other auth methods:
  • Custom JWT — For Auth0, Firebase, Supabase, Clerk, or OIDC providers
  • Privy — For Privy social login and embedded wallets