# Security

> PCI scope, how keys and secrets are handled, and what Borga expects from your integration.

Source: https://docs.borga.is/security

## PCI scope

Card details are entered into the card processor's own iframe, served from its PCI DSS Level 1 environment, on both the hosted page and inside the embedded modal. Neither your servers nor Borga's ever see a card number, expiry or CVC. Borga receives a token for repeat charges, plus the brand, last four digits and expiry for display.

This places merchants using Borga in **SAQ A**, the lightest self-assessment questionnaire, for both hosted and embedded checkout.

## Credentials

- **Secret keys** are stored as bcrypt hashes and shown once. Use one key per environment, keep them in a secret store, and rotate under **Developers** if one may have leaked. Rotation revokes the old key immediately.
- **Publishable keys** are safe in browsers. They can only create embedded sessions from origins on their allow-list, for a merchant-controlled amount.
- **Client secrets** (`pcs_…`) authorise one checkout session for 24 hours and are returned once. Pass them to the browser over HTTPS and nowhere else.
- **Webhook signing secrets** are 48 characters of entropy, encrypted at rest, and shown once. Verify every delivery; see [Webhooks](/webhooks).

## Transport and data

All endpoints are HTTPS only with HSTS. API requests and responses are logged with their `request_id` but request bodies are not logged. Accounting-provider tokens are encrypted with AES-256-GCM. Test and live data are partitioned by mode on every query.

## Isolation between surfaces

`checkout.borga.is` runs on its own origin with no shared cookies and a strict Content Security Policy, and only talks to a small set of public endpoints that authenticate with the session id (and the client secret for embedded sessions). Merchant APIs are never exposed there. `dashboard.borga.is` authenticates with Kenni electronic ID and is separate from the API-key surface.

## What Borga expects from you

- Fulfil from verified webhooks, not from redirect parameters or browser callbacks.
- Register only the domains you own as redirect domains and publishable-key origins, and use HTTPS everywhere.
- Set a Content Security Policy on pages that load borga.js; see [Embedded checkout](/payments/embedded-checkout#content-security-policy).
- Send an `Idempotency-Key` on POSTs that move money so retries cannot double-charge.

## Reporting a vulnerability

Email [security@borga.is](mailto:security@borga.is) with details and a way to reach you. Please do not test against live merchants; test mode is free and identical in behaviour.
