GNETiX Docs
Architecture

Security

Authentication, encryption, and tenant isolation

GNETiX enforces security at every layer -- from authentication and encryption to strict tenant isolation in the database.

Authentication

JWT Tokens

All API requests (except login, registration, and health checks) require a valid JWT access token in the Authorization: Bearer header.

Token TypeLifetimePurpose
Access token15 minutesAuthenticates API requests
Refresh token7 daysObtains new access tokens without re-login

When an access token expires, the frontend silently obtains a new one using the refresh token. If the refresh token is also expired, the user is redirected to the login page.

Password Hashing

User passwords are hashed using bcrypt via the passlib library. Plaintext passwords are never stored or logged.

Duo MFA

Organizations can enable Duo Security multi-factor authentication. When configured, users must complete a Duo push, SMS, or TOTP challenge after entering their password. Duo MFA is configured per-organization by an admin.

Encryption at Rest

All sensitive fields are encrypted before being written to the database using Fernet symmetric encryption (from the cryptography library). Encrypted fields include:

  • LLM provider API keys
  • AWS access keys and secret keys
  • Azure endpoint URLs
  • OAuth client secrets for MCP server authentication
  • Webex, Slack, and Teams bot tokens

The Fernet key is loaded from the environment (FERNET_KEY) and is never stored in the database or committed to source control.

The Fernet key is the root of trust for all encrypted data. If it is lost, all encrypted fields become unrecoverable. Back up this key securely and rotate it with a key migration process.

Tenant Isolation

GNETiX is a multi-tenant system. Every database table that contains tenant-specific data includes an org_id column, and every query is scoped to the requesting user's organization.

# Every query includes the org_id filter
result = await session.execute(
    select(Agent).where(
        Agent.org_id == current_user.org_id
    )
)

This is enforced at the application layer through dependency injection. The org_id is extracted from the JWT token and passed to every service function. There are no admin endpoints that bypass tenant scoping except for superuser-only operations explicitly designed for cross-tenant management.

Tenant isolation is a security boundary, not a convenience. Every database query must include an org_id filter. Omitting it is treated as a security defect.

Agent Call-Home Tokens

On-prem agents authenticate with the backend using call-home tokens:

  1. An admin registers an agent in the UI, which generates a 32-byte cryptographically random hex token.
  2. The token is displayed once to the admin for configuration on the agent.
  3. The backend stores only the bcrypt hash of the token -- the plaintext is never persisted.
  4. When the agent connects via WebSocket, it presents the token. The backend verifies it against the stored hash.

This ensures that even if the database is compromised, call-home tokens cannot be extracted or reused.

CORS

The backend enforces CORS restrictions, allowing requests only from the configured frontend origin. The wildcard origin (*) is never used.

# CORS is restricted to the frontend origin
allow_origins=[settings.frontend_url]

Role Hierarchy

GNETiX uses a four-level role hierarchy. Each role inherits all permissions of the roles below it.

RoleLevelScopeKey Permissions
user1Own orgSend messages, view permitted tools
org_admin2Own orgManage users, agents, MCP servers, LLM config, guardrails
msp_admin3Multiple orgsManage multiple organizations (managed service provider)
superuser4GlobalFull system access, create organizations, manage all tenants

Role checks are enforced on every API endpoint through dependency injection. Attempting to access an endpoint above your role level returns a 403 Forbidden response.

Platform Access Controls

In addition to roles, each user has per-platform access toggles:

ToggleEffect
webex_enabledUser can interact via Cisco Webex
slack_enabledUser can interact via Slack
teams_enabledUser can interact via Microsoft Teams

These toggles allow org admins to control which messaging platforms each user is authorized to use, independent of their role level.