Skip to content

Security

Authentication

Multi-Layer Auth Model

Layer Method Details
Customer onboarding Tripletex OAuth2 Standard OAuth2 authorization code flow
API requests to Tripletex Session token (Basic Auth) Auto-refreshing, 1-hour TTL
Conversation Agent → Accounting API Internal service auth (mTLS / signed JWT) Every POST /solve call is authenticated
Slack bot → Conversation Agent OAuth2 bot token + event signature verification HMAC-SHA256 on every webhook
Email webhook → Conversation Agent DKIM verification + shared secret Reject unsigned or unverified emails
Dashboard OAuth2 (Google/Microsoft SSO) No password-based auth
Accounting providers OAuth2 per provider TripletexProvider (session tokens), FikenProvider (bearer tokens)
LLM providers API keys via secret manager GCP Secret Manager or Vault

Token Storage

All tokens and secrets are encrypted at rest using AES-256-GCM with per-tenant encryption keys. The master key is stored in GCP Secret Manager (or HashiCorp Vault for self-hosted).

Token lifecycle:
1. Received from OAuth flow
2. Encrypted with tenant-specific DEK (data encryption key)
3. DEK wrapped with KEK (key encryption key) in Secret Manager
4. Stored as BYTEA in PostgreSQL
5. Decrypted in-memory only when needed for API calls
6. Never logged, never returned in API responses

Encryption

In Transit

Connection Protocol
User to dashboard TLS 1.3 (Cloudflare)
Slack webhook TLS 1.3
Email webhook TLS 1.2+
Backend to Tripletex TLS 1.2+
Backend to LLM providers TLS 1.3
Database connections TLS 1.3 with certificate pinning

At Rest

Data Encryption
OAuth tokens AES-256-GCM (envelope encryption via KMS)
Audit trail Database-level encryption (PostgreSQL TDE)
Company config Database-level encryption
PDF attachments AES-256-GCM per file, stored in GCS with CMEK
Backups Encrypted with separate backup key in KMS

Bokforingsloven Compliance

The Norwegian Bookkeeping Act (bokforingsloven) imposes specific requirements on accounting systems. The AI Accountant is designed to enforce these.

Requirements and Implementation

Requirement Law Reference Implementation
Every transaction must be documented Section 10 Audit trail logs every API call with full context
Documents must be stored for 5 years (primary: 10 years) Section 13 Retention policy: audit trail 10 years, attachments 10 years
Transactions must be recorded without undue delay Section 7 Real-time processing via Slack/email, automated cron
Audit trail must show who, when, what Section 13a user_id, timestamp, action_type, resource_id on every entry
No deletion of accounting records Section 13 Soft delete only; undone_at field marks reversals, original entry preserved
Sequential numbering of vouchers Section 7 Enforced by Tripletex; validated by ComplianceEngine
Separation of duties Section 2 Role-based access: employee, manager, accountant, admin

Undo Mechanism

Instead of deleting, the AI Accountant creates a reversing entry:

Original: V-2026-0340 — Debit 6010 (2,500 kr), Credit 1089 (2,500 kr)
Undo:     V-2026-0341 — Debit 1089 (2,500 kr), Credit 6010 (2,500 kr)
                        Description: "Reversering av V-2026-0340"

Both entries are preserved in the audit trail. The undo window is 24 hours.


Data Handling

What We Store

Data Location Retention
Audit trail PostgreSQL 10 years
Company config (tokens, rules) PostgreSQL Active + 1 year after cancellation
Employee identity mapping PostgreSQL Active + 90 days
Context cache (departments, accounts) PostgreSQL 1 hour TTL
PDF attachments GCS bucket 10 years
LLM conversation logs None Not stored

What We Do NOT Store

  • Financial transactions (Tripletex is system of record)
  • Account balances
  • Personal salary data
  • Bank account numbers (only referenced via Tripletex IDs)
  • LLM conversation history beyond the current task

Data Isolation

Each company's data is logically isolated:

  • All database queries include company_id filter
  • Row-level security (RLS) enforced at the PostgreSQL level
  • GCS buckets use per-tenant prefixes with IAM policies
  • No cross-tenant data access is possible, even in error

GDPR Compliance

Right Implementation
Right to access Export endpoint: GET /api/company/:id/export
Right to erasure Delete company data (except bokforingsloven-required records)
Right to portability JSON export of all stored data
Data minimization Only store what is needed for audit and operation
Privacy by design No personal data in LLM prompts beyond necessary context

LLM Data Handling

Concern Mitigation
Data sent to LLM Minimal: task description + relevant context only
Employee names in prompts Used for identity resolution, not stored by LLM
Financial figures Sent only when needed for calculations
LLM training Both Gemini (Vertex AI) and Claude API have no-training guarantees
Conversation logs Not persisted; each task is a fresh context

Access Control

Role-Based Access

Role Can Do Cannot Do
employee Submit expenses, ask questions, request invoices Approve expenses, run payroll, close month
manager Approve expenses up to threshold, view department budgets Close month, modify rules
accountant All accounting operations, close month, bank reconciliation Modify system rules, manage users
admin Everything, including rules and user management N/A

Principle of Least Privilege

  • Read-only queries require employee role minimum
  • Write operations check role + approval thresholds
  • Sensitive operations (payroll, month-end) require accountant or above
  • Rule changes require admin
  • All role checks happen in the RulesEngine before any Tripletex API call

Incident Response

Severity Example Response Time Action
Critical Token leak, unauthorized access 15 minutes Revoke all tokens, notify customers, rotate keys
High Data exposure, API abuse 1 hour Investigate, patch, notify affected customers
Medium Failed auth attempts, rate limit abuse 4 hours Block source, review logs
Low Minor policy violation 24 hours Log, review in next audit