Skip to content

Technical reference

Zielgruppe:Provider (ISN Systems) — Deployment, Architecture, Debugging

Architecture

Browser → Traefik (443)
    auth-check Middleware (ForwardAuth)
    GET http://auth-service:8091/verify
    Auth-Service (PHP 8.4 + SQLite)
      ├── Route in protected_routes?
      │     ├── Nein → 200 OK (durchlassen)
      │     └── Ja → Cookie pruefen
      │           ├── Gueltig → 200 OK + X-Auth-* Header
      │           └── Ungueltig → 302 → auth.xynap.tech/login
    Backend-Service

Components

Component Technology Location
Auth service PHP 8.4 (build-in server) /usr/local/xynap/auth-service/
Database SQLite 3 /var/lib/xynap/auth-service/auth.db(volume)
CSRF-Secret File /var/lib/xynap/auth-service/auth.db.csrf_secret
Templates HTML /usr/local/xynap/auth-service/templates/
Containers Docker auth-service(Port 8091 Internal)

Database Schema

Table:users

Column Type Description
id INTEGER PK Auto-Increment
email TEXT UNIQUE Login email (lowercase)
password TEXT bcrypt hashash (cost=12)
name TEXT Display name
status TEXT pending / active / blocked
role TEXT user / admin
created_at DATE Registration date
approved_at DATE Release date
last_login DATE Last login

Table:sessions

Column Type Description
token TEXT PK 64 characters Hex tokens (session ID)
user_id INTEGER Reference tousers.id
ip TEXT IP of login
user_agent TEXT Browser User-Agent
created_at DATE Session start
expires_at DATE Expiration time (TTL: 24h)

Table:protected_routes

Column Type Description
id INTEGER PK Auto-Increment
host TEXT Domain (e.g.ai.xynap.tech)
path TEXT URL path (e.g./)
description TEXT Short description
required_role TEXT useroradmin
enabled INDUSTRY 1 = active, 0 = inactive
created_at DATE Date of creation

Table:login_attempts

Column Type Description
ip TEXT Source-IP
attempted_at DATE Date of failure

Traefik integration

Middleware definition

In the Docker-Compose (/etc/xynap/stack/docker-compose.yml) on theauth-servicecontainer:

labels:
  - "traefik.http.middlewares.auth-check.forwardauth.address=http://auth-service:8091/verify"
  - "traefik.http.middlewares.auth-check.forwardauth.trustForwardHeader=true"
  - "traefik.http.middlewares.auth-check.forwardauth.authResponseHeaders=X-Auth-User,X-Auth-Name,X-Auth-Role"

Insert Middleware

To provide a service, addauth-checkto the middleware chain:

labels:
  - "traefik.http.routers.mein-service.middlewares=crowdsec@file,security-headers@file,rate-limit-standard@file,auth-check"

Response header

With successful authentication, the Auth-Service sets the following headers that are forwarded to the backend:

Header Contents Example
X-Auth-User User's email admin@xynap.tech
X-Auth-Name Display name Admin
X-Auth-Role User role admin

Backend services can evaluate these headers to implement user-based logic.

Characteristics Value
Name __xynap_auth
Domain: .xynap.tech
Path /
Secure true(only HTTPS)
HttpOnly true(no JavaScript access)
Samesite Lax
Max-Age 86400 seconds (24 hours)

Cookie domain notice

The cookie applies only to*.xynap.tech. Services under other domains (e.g.xynap.cloud,xynap.eu) can not read the cookie ** and must use the route protection in the SQLite-DB to be recognized as damaged by/verify. The login redirect works, but the cookie will only be set for.xynap.techafter login — the user will be redirected to login again for services under other domains.

Endpoints

Path Method Description
/verify GET ForwardAuth-Endpoint (Traefik calls this)
/login GET/POST Login page and form processing
/register GET/POST Registration page
/logout GET End session, Like cookie
/admin GET/POST Admin panel (role=adminonly)

Deployment

Container configuration

The Auth-Service releases as a Docker container in the xynap stack:

# Container-Status pruefen
sudo docker ps --filter "name=auth-service"

# Logs anzeigen
sudo docker compose -f /etc/xynap/stack/docker-compose.yml logs -f auth-service

# Neustart
sudo docker compose -f /etc/xynap/stack/docker-compose.yml restart auth-service

# Rebuild (nach Code-Aenderungen)
sudo docker compose -f /etc/xynap/stack/docker-compose.yml up -d --build auth-service

Environment variables

Variable Default Description
AUTH_COOKIE_DOMAIN .xynap.tech Cookie domain
AUTH_SESSION_TTL 86400 Session duration in seconds
AUTH_DB_PATH /data/auth.db Path to SQLite database
AUTH_FIRST_USER_ADMIN true First user becomes admin

Database access (debugging)

Since the container has nosqlite3CLI, access via PHP:

# Alle Benutzer auflisten
sudo docker exec auth-service php -r "
\$db = new PDO('sqlite:/data/auth.db');
foreach(\$db->query('SELECT id, email, status, role, last_login FROM users') as \$r)
    echo implode(' | ', \$r) . PHP_EOL;
"

# Alle geschuetzten Routen anzeigen
sudo docker exec auth-service php -r "
\$db = new PDO('sqlite:/data/auth.db');
foreach(\$db->query('SELECT host, path, required_role, enabled FROM protected_routes ORDER BY host') as \$r)
    echo implode(' | ', \$r) . PHP_EOL;
"

# Aktive Sessions zaehlen
sudo docker exec auth-service php -r "
\$db = new PDO('sqlite:/data/auth.db');
echo \$db->query(\"SELECT COUNT(*) FROM sessions WHERE expires_at > datetime('now')\")->fetchColumn() . ' aktive Sessions' . PHP_EOL;
"

Troubleshooting

?? bug "Login Redirect loop" Symptom:After login you will be immediately redirected to login.

**Ursachen:**

1. **Cookie-Domain stimmt nicht:**Service does not operate under`*.xynap.tech`
2. **Session abgelaufen:**TTL pruefen (`AUTH_SESSION_TTL`)
3. **HTTPS-Problem:**Cookie is`Secure=true`, only works via HTTPS

**Diagnose:**
```bash
# Verify-Endpoint direkt testen
curl -v -H "Host: ai.xynap.tech" http://auth-service:8091/verify

# Cookie manuell pruefen
curl -v -b "__xynap_auth=TOKEN_HIER" -H "Host: ai.xynap.tech" http://auth-service:8091/verify
```

bug "403 Forbidden despite login" Ursache:The route requiresadmin, but the user has onlyuser.

ConvertLoesung:route touserin the admin panel or assign the admin role to the user.

?? bug "Service is open even though it should be done" Checkliste:

1. Does the service`auth-check`have in its Traefik-Middleware-Chain?
2. Does an active route exist in`protected_routes`for the domain?
3. Is the route`enabled = 1`?

If only the Traefik middleware is missing,/verifyis never called — but if only the DB route is missing,/verifyautomatically gives200 OKto the outside.

Beidemust be configured: Traefik-Middleware ** and** DB-Route.

bug "Rate-Limiting takes too frueh" Symptom:Users are blocked after a few attempts.

Ursache:Several users share an open IP (NAT/VPN).

CustomizeLoesung:Rate-Limit settings inconfig.php:

'rate_limit_window' => 300,   // Fenster in Sekunden
'rate_limit_max'    => 10,    // Max Fehlversuche