PassGate

password-as-a-service

One password. Verified everywhere.Never exposed anywhere.

Set a password once in the PassGate console. Any external site can ask “is this password correct?” through the API and receive only yes plus a short-lived signed unlock token — never the password itself.

The password stays home

Integrated sites only send the typed password and get yes or no back. The password itself is readable through one private reveal key you control.

Signed unlock tokens

A correct password returns an HMAC-signed token with your own expiry. The integrating site unlocks content and can re-validate the token anytime.

Built-in abuse control

API keys, allowed-origin lists, per-hour attempt limits and a full audit log of every attempt with origin and IP.

API reference

POST /api/public/v1/verify
headers:
  content-type: application/json
  x-api-key: pgk_live_xxxxxxxx

body:
  { "password": "user input" }

200 OK
  { "valid": true, "token": "...", "expiresAt": 1750000000 }

401 / 403 / 429
  { "valid": false, "reason": "wrong_password" }
GET /api/public/v1/password
headers:
  x-api-key: pgr_live_xxxxxxxx   (reveal key)

200 OK
  { "ok": true, "password": "N2WS-ESPM-4QH9",
    "nextRotationAt": "2026-01-01T12:00:00Z" }

401
  { "ok": false, "reason": "invalid_api_key" }
POST /api/public/v1/session
body:
  { "token": "unlock token" }

200 OK
  { "valid": true, "expiresAt": 1750000000 }

401
  { "valid": false, "reason": "expired" }

Drop-in integration snippet

<script>
async function unlock(password) {
  const res = await fetch("https://passgate.eip.lat/api/public/v1/verify", {
    method: "POST",
    headers: { "content-type": "application/json", "x-api-key": "YOUR_API_KEY" },
    body: JSON.stringify({ password }),
  });
  const data = await res.json();
  if (data.valid) {
    sessionStorage.setItem("unlock_token", data.token);
    document.body.classList.add("unlocked"); // show protected content
  } else {
    alert(data.message); // wrong password
  }
}
</script>