PIN Gate Authentication - Bypass Guide¶
Quick reference for app teams on how PIN gate authentication works and when it applies.
TL;DR¶
- Internal API calls via
127.0.0.1:PORT→ No PIN required (bypasses NGINX) - Localhost domain calls → No PIN required (auth service exempts localhost)
- Browser requests → PIN required once per session, cookie shared across
*.nominate.ai - Playwright tests → Need to authenticate with PIN in test setup
How It Works¶
All public-facing *.nominate.ai sites are protected by PIN gate authentication. When a user visits a protected site:
- NGINX checks for a valid session cookie
- If no cookie → redirect to
/auth/pin - User enters PIN (
862509) - Cookie set for
.nominate.aidomain - All subsequent requests to any
*.nominate.aisubdomain are authenticated
When PIN is NOT Required¶
Internal Service-to-Service Calls¶
If your backend needs to call another API, use the internal address:
# ✅ Correct - bypasses NGINX, no PIN needed
response = requests.get("http://127.0.0.1:32321/api/endpoint")
# ❌ Wrong - goes through NGINX, will fail without cookie
response = requests.get("https://ky04api.nominate.ai/api/endpoint")
Port Reference¶
| Service | Internal Address |
|---|---|
| tenant-manager-frontend | 127.0.0.1:32200 |
| tenant-manager API | 127.0.0.1:32201 |
| auth service | 127.0.0.1:32202 |
| testsite frontend | 127.0.0.1:32300 |
| testsite API | 127.0.0.1:32301 |
| mi20 frontend | 127.0.0.1:32310 |
| mi20 API | 127.0.0.1:32311 |
| ky04 frontend | 127.0.0.1:32320 |
| ky04 API | 127.0.0.1:32321 |
Playwright Testing¶
Playwright runs in a browser context and will hit the PIN gate. Options:
Option 1: Authenticate in Test Setup (Recommended)¶
// In your test setup / beforeAll
test.beforeAll(async ({ page }) => {
await page.goto('https://yoursite.nominate.ai/auth/pin');
await page.fill('input[name="pin"]', '862509');
await page.click('button[type="submit"]');
// Cookie is now set for all *.nominate.ai
});
Option 2: Reuse Auth State¶
// Save auth state after first login
await page.context().storageState({ path: 'auth.json' });
// Reuse in other tests
const context = await browser.newContext({ storageState: 'auth.json' });
Questions?¶
Contact the infrastructure team or check cbauth INFRA-GUIDE.
Last updated: 2026-01-02