Skip to Content
🔐 Closed Beta – Jetzt auf die Warteliste eintragen! Limitierte Plätze für Early Adopters →
De AtAPIAPI Sicherheit & Authentifizierung

API Sicherheit & Authentifizierung

💬

Hallo, ich bin Sophie! 👋 Sicherheit bei der API-Integration ist entscheidend - schließlich verarbeitest Sie sensible Geschäftsdaten. In diesem Guide erkläre ich Ihnen alle Authentifizierungsmethoden und Sicherheits-Best-Practices im Detail.

🔐

DSGVO Art. 32 & BAO §132: Alle API-Zugriffe werden protokolliert und 7 Jahre aufbewahrt. Sie sind als API-Nutzer mitverantwortlich für die sichere Handhabung Ihrer Zugangsdaten.


Übersicht der Authentifizierungsmethoden


API-Key Authentifizierung

Die einfachste und häufigste Methode für Server-zu-Server-Kommunikation. Ein API-Key gehört zu Ihrem Konto und hat Zugriff auf alle Ihre Geschäftsdaten.

API-Key erstellen

Dashboard öffnen

Melde Sie bei BuchhaltGenie an und navigiere zu Einstellungen > API-Zugang > Schlüssel verwalten.

Neuen Schlüssel erstellen

Klicken Sie auf Neuen API-Schlüssel erstellen und vergib einen aussagekräftigen Namen.

💡

Sophie’s Tipp: Verwende beschreibende Namen wie ERP-Integration-Prod oder Website-Rechnungen. So erkennst Sie später sofort, wofür welcher Schlüssel verwendet wird.

Schlüssel kopieren und sichern

🚨

Kritisch: Der Schlüssel wird nur einmal angezeigt! Kopieren Sie ihn sofort in Ihren Passwort-Manager oder Secret Store. Wenn Sie ihn verlierst, musst Sie einen neuen erstellen.

Schlüsseltypen

TypPräfixVerwendungUmgebung
Livesk_live_ProduktionsumgebungEchte Daten
Testsk_test_Sandbox/EntwicklungTestdaten

Bearer Token Format

Sende den API-Key im Authorization-Header als Bearer Token:

curl -X GET "https://buchhaltgenie.at/api/v1/invoices" \ -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -H "Accept: application/json"

Key-Rotation Best Practices

Regelmäßige Key-Rotation erhöht die Sicherheit erheblich:

EmpfehlungFrequenzGrund
RotationAlle 90 TageMinimiert Risiko bei unentdecktem Leak
Nach MitarbeiteraustrittSofortZugang entziehen
Nach SicherheitsvorfallSofortPotenziell kompromittierte Keys invalidieren

Neuen Key erstellen

Erstelle einen neuen API-Key bevor Sie den alten löschst.

Anwendungen aktualisieren

Aktualisiere alle Anwendungen auf den neuen Key.

Testen

Überprüfe, dass alle Integrationen mit dem neuen Key funktionieren.

Alten Key löschen

Erst wenn alles funktioniert, lösche den alten Key.

⚠️

Wichtig: Lösche niemals einen Key ohne vorher einen neuen einzurichten! Sonst sind Ihre Integrationen offline.


JWT Tokens

JSON Web Tokens (JWTs) sind kurzlebige, signierte Tokens, die für zeitlich begrenzte Authentifizierung verwendet werden.

Was sind JWTs?

Ein JWT besteht aus drei Teilen, getrennt durch Punkte:

header.payload.signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiJ1c2VyXzEyMzQ1IiwiYnVzaW5lc3NfaWQiOiJidXNfNjc4OTAiLCJzY29wZXMiOlsiaW52b2ljZXM6cmVhZCJdLCJleHAiOjE3MDQwNjcyMDB9. abc123signature
TeilInhaltBeschreibung
Header{"alg":"HS256","typ":"JWT"}Signatur-Algorithmus
PayloadUser ID, Scopes, AblaufzeitDie eigentlichen Daten
SignatureHMAC-SHA256 HashIntegritätsprüfung
📚

Wichtig: JWTs sind signiert, nicht verschlüsselt. Der Payload kann von jedem gelesen werden! Speichern Sie niemals sensible Daten im JWT.

Token-Lebensdauer

Token-TypLebensdauerVerwendung
Access Token1 StundeAPI-Anfragen
Refresh Token7 TageAccess Token erneuern
API-KeyUnbegrenztBis zur manuellen Löschung

Refresh-Token Flow

Wenn Ihr Access Token abläuft, kannst Sie mit dem Refresh Token einen neuen anfordern:

┌─────────────┐ ┌─────────────┐ │ Client │ │ API Server │ └──────┬──────┘ └──────┬──────┘ │ │ │ 1. API Request mit Access Token │ │ ─────────────────────────────────────────► │ │ │ │ 2. 401 Unauthorized (Token expired) │ │ ◄───────────────────────────────────────── │ │ │ │ 3. POST /oauth/token (Refresh Token) │ │ ─────────────────────────────────────────► │ │ │ │ 4. Neues Access Token + Refresh Token │ │ ◄───────────────────────────────────────── │ │ │ │ 5. API Request mit neuem Access Token │ │ ─────────────────────────────────────────► │ │ │ │ 6. 200 OK (Erfolg) │ │ ◄───────────────────────────────────────── │ │ │
⚠️

Sicherheitshinweis: Refresh Tokens müssen sicher gespeichert werden (z.B. verschlüsselt in einer Datenbank). Sie dürfen niemals im Frontend oder in Logs erscheinen!


OAuth 2.0 für Partner

OAuth 2.0 ermöglicht es Ihrer Anwendung, im Namen verschiedener BuchhaltGenie-Benutzer zu agieren - ideal für Partner-Integrationen und Multi-Mandanten-Software.

Wann OAuth 2.0 verwenden?

SzenarioEmpfehlung
Eigene Buchhaltung automatisierenAPI-Key
SaaS-Produkt für mehrere KundenOAuth 2.0
Partner-IntegrationOAuth 2.0
Mobile AppOAuth 2.0
Server-zu-Server (eigene Daten)API-Key

Partner-Registrierung

Bevor Sie OAuth 2.0 nutzen kannst, musst Sie Ihre Anwendung registrieren:

Partner-Antrag stellen

Kontaktiere office@buchhaltgenie.at mit:

  • Firmenname und UID-Nummer
  • Beschreibung Ihrer Anwendung
  • Geplante Scopes
  • Redirect URIs

Prüfung (1-3 Werktage)

Wir prüfen Ihren Antrag und kontaktieren Sie bei Fragen.

Credentials erhalten

Sie erhalten:

  • client_id - Öffentliche Kennung
  • client_secret - Geheim halten!

Authorization Code Flow

Der sicherste OAuth 2.0 Flow für Server-seitige Anwendungen:

1. Benutzer zur Autorisierung senden

Leite den Benutzer zu unserer Autorisierungsseite:

GET https://auth.buchhaltgenie.at/oauth/authorize? client_id=YOUR_CLIENT_ID& redirect_uri=https://Ihre-app.at/callback& response_type=code& scope=invoices:read invoices:write customers:read& state=RANDOM_STATE_STRING
ParameterPflichtBeschreibung
client_idJaIhre Client ID
redirect_uriJaRegistrierte Callback-URL
response_typeJaImmer code
scopeJaGewünschte Berechtigungen
stateJa!CSRF-Schutz (zufälliger String)
🚨

CSRF-Schutz: Der state Parameter ist Pflicht! Generiere einen zufälligen String, speichere ihn in der Session und prüfe ihn beim Callback.

2. Benutzer autorisiert

Der Benutzer sieht eine Übersicht der angeforderten Berechtigungen und kann zustimmen oder ablehnen.

3. Authorization Code erhalten

Nach Zustimmung wird der Benutzer zurückgeleitet:

https://Ihre-app.at/callback? code=AUTHORIZATION_CODE& state=RANDOM_STATE_STRING

4. Code gegen Token tauschen

curl -X POST "https://auth.buchhaltgenie.at/oauth/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "code=AUTHORIZATION_CODE" \ -d "redirect_uri=https://Ihre-app.at/callback"

Antwort:

{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "rt_xxxxxxxxxxxxxxxx", "token_type": "Bearer", "expires_in": 3600, "scope": "invoices:read invoices:write customers:read" }

5. API aufrufen

curl -X GET "https://buchhaltgenie.at/api/v1/invoices" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Verfügbare Scopes

ScopeBeschreibungBerechtigung
invoices:readRechnungen lesenLesend
invoices:writeRechnungen erstellen/bearbeitenSchreibend
customers:readKundendaten lesenLesend
customers:writeKundendaten bearbeitenSchreibend
transactions:readTransaktionen lesenLesend
transactions:writeTransaktionen erstellenSchreibend
reports:readBerichte abrufenLesend
sophie:chatSophie AI nutzenInteraktiv
adminVoller ZugriffAlle
💡

Sophie’s Tipp: Fordere nur die Scopes an, die Ihre Anwendung wirklich braucht! Das erhöht das Vertrauen der Benutzer und minimiert Risiken bei einem Sicherheitsvorfall.

Redirect URIs

Redirect URIs müssen bei der Partner-Registrierung angegeben werden:

UmgebungBeispiel
Produktionhttps://Ihre-app.at/oauth/callback
Staginghttps://staging.Ihre-app.at/oauth/callback
Entwicklunghttp://localhost:3000/oauth/callback
⚠️

Sicherheit: In Produktion sind nur HTTPS-URLs erlaubt! localhost ist nur für Entwicklung gestattet.


Sicherheitsmaßnahmen

HTTPS Pflicht

Alle API-Kommunikation muss über HTTPS erfolgen:

✅ https://buchhaltgenie.at/api/v1/... ❌ http://buchhaltgenie.at/api/v1/... (wird abgelehnt!)
AnforderungStatus
TLS VersionMinimum TLS 1.2, empfohlen TLS 1.3
ZertifikatGültig, nicht abgelaufen
Cipher SuitesNur moderne, sichere Suites
HTTPWird mit 301 zu HTTPS redirected
🔒

Pflicht: API-Anfragen über HTTP werden abgelehnt. Es gibt keine Ausnahmen - auch nicht für Entwicklung oder Testing.

Rate Limiting

Um eine faire Nutzung für alle zu gewährleisten, gelten Rate Limits:

Standard-Limits nach Tarif

TarifAnfragen/MinuteAnfragen/TagBurst-Limit
Starter601.00010
Pro30010.00050
Business60050.000100
EnterpriseIndividuellIndividuellIndividuell

Admin-Operationen

Für sensible Admin-Operationen gelten strengere Limits:

OperationLimitZeitfensterGrund
Credit-Operationen10015 MinutenBAO §132 Compliance
Benutzer-Management10015 MinutenDSGVO Art. 32
Webhook-Retry5015 MinutenRessourcen-Schutz
Report-Generierung51 StundeRechenintensiv

Rate Limit Headers

Jede API-Antwort enthält Informationen über Ihr aktuelles Kontingent:

HTTP/1.1 200 OK X-RateLimit-Limit: 300 X-RateLimit-Remaining: 287 X-RateLimit-Reset: 1704067200

Rate Limit überschritten

Bei Überschreitung erhältst Sie HTTP 429:

{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Anfragelimit überschritten. Bitte warte 32 Sekunden.", "details": { "retry_after": 32, "limit": 300, "reset_at": "2026-01-16T15:30:00Z" } } }

Implementiere exponentielles Backoff:

async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3): Promise<Response> { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch(url, options); if (response.status === 429) { const retryAfter = parseInt(response.headers.get('Retry-After') || '1'); const waitTime = retryAfter * 1000 * Math.pow(2, attempt); // Exponentielles Backoff console.log(`Rate limit erreicht. Warte ${waitTime}ms...`); await new Promise(resolve => setTimeout(resolve, waitTime)); continue; } return response; } throw new Error('Max retries exceeded'); }

IP-Whitelisting (Enterprise)

Enterprise-Kunden können API-Zugriffe auf bestimmte IP-Adressen beschränken:

Einstellungen öffnen

Navigiere zu Einstellungen > API-Zugang > Sicherheit.

IP-Whitelist aktivieren

Aktiviere IP-Whitelist und füge Ihre Server-IPs hinzu.

IPs konfigurieren

{ "ip_whitelist": [ "203.0.113.10", // Einzelne IP "203.0.113.0/24", // IP-Range (CIDR) "2001:db8::1" // IPv6 ] }
💡

Sophie’s Tipp: IP-Whitelisting ist ideal für feste Server-Standorte. Bei dynamischen IPs (z.B. Cloud-Funktionen) ist es oft nicht praktikabel - setze dann besonders auf sichere Key-Aufbewahrung.

CORS Konfiguration

Cross-Origin Resource Sharing (CORS) ist für Browser-basierte Anwendungen relevant:

OriginErlaubtHinweis
Registrierte DomainsBei Partner-Registrierung angeben
localhost:*Nur für Entwicklung
*.buchhaltgenie.atEigene Domains
Unbekannte OriginsWird blockiert

CORS-Header in der Antwort:

Access-Control-Allow-Origin: https://Ihre-app.at Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Authorization, Content-Type, Accept Access-Control-Max-Age: 86400
⚠️

Wichtig: Für Server-zu-Server-Kommunikation ist CORS nicht relevant - es betrifft nur Browser! Ihre Backend-Anwendung kann ohne CORS-Einschränkungen auf die API zugreifen.


Fehlerbehandlung

HTTP-Statuscodes

CodeBedeutungBeschreibungAktion
401UnauthorizedAPI-Key ungültig/fehltKey prüfen, neu authentifizieren
403ForbiddenKeine BerechtigungScope prüfen, Admin kontaktieren
429Too Many RequestsRate Limit überschrittenWarten, Backoff implementieren

401 Unauthorized

{ "error": { "code": "UNAUTHORIZED", "message": "Ungültiger oder fehlender API-Schlüssel.", "details": { "hint": "Prüfe den Authorization-Header (Bearer Token Format)" } } }

Häufige Ursachen:

  • API-Key fehlt oder ist falsch formatiert
  • API-Key wurde gelöscht oder deaktiviert
  • Access Token ist abgelaufen (bei OAuth)
// Fehlerbehandlung const response = await fetch('/api/v1/invoices', { headers: { 'Authorization': `Bearer ${apiKey}` } }); if (response.status === 401) { // Bei OAuth: Token erneuern if (isOAuthToken) { await refreshAccessToken(); // Anfrage wiederholen } else { // Bei API-Key: Key prüfen console.error('API-Key ungültig - bitte in den Einstellungen prüfen'); } }

403 Forbidden

{ "error": { "code": "FORBIDDEN", "message": "Sie haben keine Berechtigung für diese Aktion.", "details": { "required_scope": "invoices:write", "your_scopes": ["invoices:read"] } } }

Häufige Ursachen:

  • Fehlender Scope bei OAuth
  • Zugriff auf fremde Ressourcen
  • Feature nicht im Tarif enthalten

429 Too Many Requests

{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Zu viele Anfragen. Bitte warte 32 Sekunden.", "details": { "retry_after": 32, "limit": 300, "window": "minute" } } }

Best Practice: Exponentielles Backoff

async function apiCall(url: string, options: RequestInit): Promise<Response> { const maxRetries = 5; let lastError: Error | null = null; for (let i = 0; i < maxRetries; i++) { try { const response = await fetch(url, options); if (response.status === 429) { const retryAfter = parseInt(response.headers.get('Retry-After') || '1'); const delay = retryAfter * 1000 * Math.pow(2, i); // Exponentiell console.warn(`Rate limit, warte ${delay}ms (Versuch ${i + 1}/${maxRetries})`); await sleep(delay); continue; } return response; } catch (error) { lastError = error as Error; } } throw lastError || new Error('Max retries exceeded'); }

DSGVO & BAO Compliance

Audit Logging (BAO §132)

Alle API-Zugriffe werden 7 Jahre protokolliert:

Protokolliertes FeldBeispielRechtsgrundlage
Zeitstempel2026-01-16T10:30:00ZBAO §132
User IDuser_12345BAO §132
IP-Adresse203.0.113.10DSGVO Art. 32
EndpointPOST /api/v1/invoicesBAO §132
AktionCREATEBAO §132
Ressourceinvoice_67890BAO §132
StatusSUCCESS / FAILEDBAO §132
📋

BAO §132 Anforderung: Alle buchhalterisch relevanten Vorgänge müssen nachvollziehbar sein. Die Audit-Logs können bei einer Betriebsprüfung angefordert werden.

Datenminimierung (DSGVO Art. 5)

Best Practices für API-Nutzung:

PrinzipUmsetzung
Nur notwendige DatenFordere nur benötigte Felder an (?fields=id,name,email)
Minimale ScopesNur Scopes anfordern, die wirklich gebraucht werden
Keine Logs mit PIILogge keine personenbezogenen Daten in Ihre Systeme
Zeitliche BegrenzungLösche lokale Kopien nach Gebrauch
// ✅ Gut: Nur benötigte Felder const response = await fetch('/api/v1/customers?fields=id,company_name'); // ❌ Schlecht: Alle Daten abrufen const response = await fetch('/api/v1/customers'); // Enthält alle Felder

Verschlüsselung

EbeneStandardBeschreibung
Transport (in transit)TLS 1.3Alle API-Verbindungen verschlüsselt
Speicherung (at rest)AES-256Datenbank und Backups verschlüsselt
SchlüsselverwaltungHSMHardware Security Module für Keys

Compliance-Checkliste für API-Nutzer

Als API-Nutzer bist Sie mitverantwortlich:

  • API-Keys sicher gespeichert (nicht im Code!)
  • HTTPS für alle Verbindungen verwendet
  • Minimale Scopes angefordert (Least Privilege)
  • Lokale Datenkopien nur bei Bedarf
  • Auftragsverarbeitungsvertrag (AVV) abgeschlossen
  • Zugriffsberechtigungen dokumentiert
  • Incident-Response-Plan vorhanden
⚖️

AVV Pflicht: Wenn Sie über die API personenbezogene Daten verarbeitest, ist ein Auftragsverarbeitungsvertrag gemäß DSGVO Art. 28 Pflicht. Kontaktiere office@buchhaltgenie.at für den AVV.


API-Schlüssel sicher aufbewahren

Richtig
// Umgebungsvariable const apiKey = process.env.BUCHHALTGENIE_API_KEY; // Secret Manager (AWS, Azure, GCP) const apiKey = await secretManager.getSecret('buchhaltgenie-api-key'); // Nur relevante Daten loggen console.log('Invoice created:', invoice.id);
Niemals!
// NIEMALS im Code! const apiKey = "sk_live_abc123"; // NIEMALS in Git! // .env Datei nicht committen! // NIEMALS loggen! console.log('API Key:', apiKey);

Empfohlene Tools

ToolVerwendungEignung
AWS Secrets ManagerCloud-AnwendungenEnterprise
Azure Key VaultAzure-UmgebungenEnterprise
HashiCorp VaultOn-PremiseAlle
1Password / BitwardenTeamsKleine Teams
UmgebungsvariablenEinfache SetupsEntwicklung

Webhook-Signaturen verifizieren

Wenn Sie Webhooks nutzt, verifiziere immer die Signatur:

import crypto from 'crypto'; function verifyWebhookSignature( payload: string, signature: string, secret: string ): boolean { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload) .digest('hex'); // Timing-sicherer Vergleich! return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(`sha256=${expectedSignature}`) ); } // Express.js Beispiel app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-buchhaltgenie-signature'] as string; const payload = req.body.toString(); if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET!)) { console.error('Ungültige Webhook-Signatur'); return res.status(401).send('Unauthorized'); } const event = JSON.parse(payload); // Event sicher verarbeiten... res.status(200).send('OK'); });
🚨

Kritisch: Verwende immer timingSafeEqual oder hash_equals für den Signaturvergleich! Ein normaler === Vergleich ist anfällig für Timing-Angriffe.


Sicherheitsvorfälle melden

Wenn Sie eine Sicherheitslücke entdeckst:

KontaktDetails
E-Mailoffice@buchhaltgenie.at
PGP-KeyVerfügbar auf buchhaltgenie.at/security 
ReaktionszeitInnerhalb von 24 Stunden (werktags)
🏆

Bug Bounty: Für schwerwiegende Sicherheitslücken bieten wir eine angemessene Belohnung. Details finden Sie in unserer Security Policy.

Bei Kompromittierung Ihrer API-Keys:

Sofort handeln

Lösche den kompromittierten Key sofort in den BuchhaltGenie-Einstellungen.

Audit-Logs prüfen

Prüfe in Einstellungen > API-Zugang > Zugriffsprotokolle auf verdächtige Aktivitäten.

Support informieren

Kontaktiere office@buchhaltgenie.at mit Details zum Vorfall.

Neuen Key erstellen

Erstelle einen neuen Key und aktualisiere Ihre Anwendungen.


Häufige Fragen

Wie lange sind API-Keys gültig?

API-Keys laufen nicht automatisch ab. Sie bleiben gültig, bis Sie sie manuell löschst. Wir empfehlen jedoch eine Rotation alle 90 Tage.

Kann ich mehrere API-Keys haben?

Ja! Wir empfehlen separate Keys für verschiedene Anwendungen und Umgebungen. So kannst Sie bei Bedarf einzelne Zugänge widerrufen.

Was passiert bei einem Sicherheitsvorfall?

Gemäß DSGVO Art. 33/34 informieren wir Sie innerhalb von 72 Stunden. Wir haben einen dokumentierten Incident-Response-Plan.

Werden API-Zugriffe protokolliert?

Ja, alle Zugriffe werden gemäß BAO §132 für 7 Jahre protokolliert. Dies dient der Nachvollziehbarkeit bei Betriebsprüfungen.

Wo werden meine Daten gespeichert?

Alle Daten werden in ISO 27001-zertifizierten Rechenzentren in Frankfurt, Deutschland gespeichert. Es findet keine Datenübertragung außerhalb der EU statt.


Nächste Schritte

⚖️

Hinweis: Diese Dokumentation dient als technische Übersicht. Für rechtliche Fragen zur DSGVO-Compliance oder Auftragsverarbeitung konsultiere bitte einen Datenschutzbeauftragten oder kontaktiere office@buchhaltgenie.at.