Authentication
ZopNight uses JWT-based authentication. All API requests (except auth endpoints) require a valid access token.
Overview
The authentication flow works as follows:
- Authenticate via login or SSO to receive an access token and refresh token
- Include the access token in the
Authorizationheader for all API requests - When the access token expires, use the refresh token to obtain a new one
- The gateway validates the JWT, extracts your organization context, and routes the request
Token Format
Authentication Providers
| Provider | Method | Description |
|---|---|---|
| Email/Password | email | Standard email and password with OTP verification |
google | OAuth 2.0 with Google accounts | |
| GitHub | github | OAuth 2.0 with GitHub accounts |
| SAML | saml | Enterprise SSO via SAML 2.0 identity providers |
Login
/auth/loginAuthenticate and receive tokens.
curl -X POST https://zopnight.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@company.com",
"password": "your-password",
"provider": "email"
}'curl -X POST https://zopnight.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"token": "<google-oauth-id-token>"
}'{
"data": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJl...",
"tenants": [
{
"id": "org_abc123",
"name": "Acme Corp"
}
],
"user": {
"email": "user@company.com",
"name": "Jane Doe"
}
}
}Signup
/auth/signupCreate a new user account.
curl -X POST https://zopnight.com/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@company.com",
"password": "secure-password",
"name": "Jane Doe"
}'After signup, verify your email using the OTP sent to your inbox.
Email Verification
/auth/email/verifyRequest a verification OTP.
curl -X POST https://zopnight.com/api/auth/email/verify \
-H "Content-Type: application/json" \
-d '{ "email": "user@company.com" }'/auth/email/otp/validateValidate the OTP code.
curl -X PATCH https://zopnight.com/api/auth/email/otp/validate \
-H "Content-Type: application/json" \
-d '{
"email": "user@company.com",
"otp": "123456"
}'Token Refresh
Access tokens are short-lived. Use the refresh token to obtain a new access token before expiry.
/auth/refreshExchange a refresh token for a new access token.
curl -X POST https://zopnight.com/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "dGhpcyBpcyBhIHJlZnJl...",
"tenantID": "org_abc123"
}'{
"data": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...(new token)",
"refreshToken": "bmV3IHJlZnJlc2ggdG9r..."
}
}Proactive Refresh
SAML SSO
Enterprise organizations can configure SAML 2.0 single sign-on with their identity provider.
/auth/saml/initiateBegin a SAML authentication flow.
curl -X POST https://zopnight.com/api/auth/saml/initiate \
-H "Content-Type: application/json" \
-d '{ "email": "user@enterprise.com" }'Returns a redirect URL to your organization's identity provider. After authentication, the IdP redirects back with a SAML assertion that is exchanged for JWT tokens.
Create Organization
/auth/v2/organisationCreate a new organization for your account.
curl -X POST https://zopnight.com/api/auth/v2/organisation \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "name": "My Company" }'Password Reset
/auth/password/forgetInitiate a password reset.
curl -X POST https://zopnight.com/api/auth/password/forget \
-H "Content-Type: application/json" \
-d '{ "email": "user@company.com" }'/auth/password/resetComplete the password reset.
curl -X POST https://zopnight.com/api/auth/password/reset \
-H "Content-Type: application/json" \
-d '{
"email": "user@company.com",
"otp": "123456",
"newPassword": "new-secure-password"
}'Logout
/auth/logoutInvalidate the current session.
curl -X POST https://zopnight.com/api/auth/logout \
-H "Authorization: Bearer <token>"Personal Access Tokens (PAT)
For CI pipelines, scripts, and other non-interactive clients, ZopNight supports Personal Access Tokens. PATs use the same Authorization: Bearer header as JWT access tokens but are validated against the auth service directly rather than through JWKS — they don't expire on the same schedule as user JWTs.
| Property | Value |
|---|---|
| Prefix | zn_pat_ followed by an opaque secret |
| Where to use | Authorization: Bearer zn_pat_... |
| Created from | The ZopNight UI under Settings → Personal Access Tokens |
| Scope | Inherits the creating user's role and permissions |
curl https://zopnight.com/api/resources \
-H "Authorization: Bearer zn_pat_xxxxxxxxxxxxxxxxxxxxxxxx"Treat PATs like passwords
Organization Context
Most JWTs include the active organization in the tenant-id ororg_id claim, and that value is used to scope every request. If a token does not carry an org claim (for example, when a user belongs to multiple orgs and the client wants to override the default), pass an explicit header:
| Header | Value | When to use |
|---|---|---|
X-Org-Id | The target organization's ID | Override the JWT's default org, or supply org context for tokens that lack one. |
Unauthenticated Endpoints
A small number of endpoints intentionally bypass JWT validation. They use other mechanisms (HMAC signatures, body-carried JWTs, or no auth at all):
| Endpoint | Authentication | Purpose |
|---|---|---|
POST /webhooks/github | HMAC-SHA256 signature in X-Hub-Signature-256 | GitHub push & PR webhooks for the deploy pipeline |
POST /build-callbacks/{revisionID} | JWT carried in the request body, signed with the build callback secret | Build runner reports back when an image is ready |
GET /.well-known/openid-configuration | Public | OIDC discovery (used by Azure Workload Identity Federation) |
GET /.well-known/jwks.json | Public | JSON Web Key Set for verifying ZopNight-issued tokens |
POST /auth/* | Varies (login, signup, refresh) | Authentication flows themselves |
Request Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <access_token | PAT> | Yes (all endpoints except those listed above) |
X-Org-Id | An organization ID | Optional — overrides the org claim in the JWT |
Content-Type | application/json | Yes (for POST/PUT/PATCH requests) |