Skip to content
Security

How Ledgeriano protects your accounting data

Your ledgers hold sensitive financial records, so we protect them in layers: encrypted connections, hashed credentials, strict access per business, entries that cannot be quietly rewritten and an audit trail of every change. This page describes what the product actually does.

Shield and padlock protecting an accounting ledger with an audit trail timeline
At a glance

The security controls built into every account

These controls are on for every customer. There is no premium security tier.

HTTPS everywhere

The website, the app and the API are served over encrypted HTTPS connections.

Hashed passwords

Passwords are stored as bcrypt hashes. Nobody at Ledgeriano can read your password.

Two-factor sign-in

Add time-based one-time codes (TOTP) from any authenticator app. The secret is encrypted at rest.

API keys shown once

Keys are stored as SHA-256 hashes, scoped to one business, and can be rotated or revoked at any time.

Role-based access

Every request is checked against the member's role and permissions in that specific business.

Posted entries are protected

Posted entries are corrected by reversal, not edited, and lock dates freeze closed periods.

Full audit trail

Who did what, when, from which IP address, with old and new values for every changed field.

Signed webhooks

Each delivery carries an HMAC-SHA256 signature over a timestamp and the body.

In detail

What happens behind each control

Account and sign-in security

Your password is never stored in readable form, and a second factor stops someone who has only your password.

  • Passwords are hashed with bcrypt before they are stored. They must be at least 8 characters and contain letters and numbers.
  • Two-factor authentication uses standard TOTP codes, so it works with common authenticator apps. The shared secret is encrypted in the database.
  • Repeated failed sign-in attempts and wrong two-factor codes are throttled, which slows down password guessing.
  • New accounts confirm their email address through a signed link.
  • The password reset form answers the same way whether or not an email is registered, so it cannot be used to discover accounts.
  • Resetting your password signs out every session. Changing it signs out all your other devices.

Sessions you can see and end

Each sign-in creates a session token that expires after 30 days, and you can revoke any session whenever you like.

  • Session tokens expire 30 days after sign-in. Expired tokens are removed from the database by a daily job.
  • Your profile lists active sessions by device and browser, and you can end any of them.
  • Signing out deletes the token on the server, not only in your browser.
  • If an account is suspended, its open sessions stop working on the next request.

API keys and API access

API keys are stored as SHA-256 hashes, so a key is shown to you exactly once, when it is created.

  • Only the business owner can create, view, rotate or revoke API keys.
  • Each key belongs to one business and cannot reach any other business.
  • Keys carry abilities: read only, or read and write. Use read-only keys for reporting tools.
  • You can set an expiry date. Revoked and expired keys are rejected on the next request.
  • Rotating a key revokes the old one and issues a new key with the same settings in a single step.
  • Each key has its own rate limit (120 requests per minute by default), reported in X-RateLimit-Limit and X-RateLimit-Remaining headers.
  • Every API request is logged with method, path, status, IP address and duration, and each key shows when and from which IP it was last used.
  • Idempotency keys let you retry a request safely without creating a duplicate entry. See the developer overview and the accounting API guide.

Signed webhooks

Every webhook delivery is signed with HMAC-SHA256 using a secret unique to that webhook, and the signature covers a timestamp so replayed messages can be rejected.

  • Deliveries include X-Ledgeriano-Signature (sha256= followed by the hex digest), X-Ledgeriano-Timestamp, X-Ledgeriano-Event and X-Ledgeriano-Delivery headers.
  • The signature is computed over the timestamp, a dot and the raw request body.
  • Each delivery has a unique ID, so your endpoint can ignore duplicates.
  • Failed deliveries are retried up to 5 times with growing delays (30 seconds, 2, 10 and 30 minutes).
  • You can rotate a webhook secret. New deliveries are signed with the new secret right away.
Verify a webhook in Node.jsCompute the signature from the raw body, compare it in constant time, and reject timestamps older than a few minutes.
import crypto from "node:crypto";

// rawBody: the exact request body string, before JSON parsing
export function verifyLedgerianoWebhook(rawBody, headers, secret) {
  const timestamp = headers["x-ledgeriano-timestamp"];
  const signature = headers["x-ledgeriano-signature"] ?? ""; // "sha256=<hex>"

  // Reject messages older than 5 minutes
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Permissions and business isolation

Each business is a separate ledger, and every request is checked against your membership and role in that business before any data is returned.

  • A user who is not an active member of a business gets an access-denied error, even with a valid session.
  • Members get roles with fine-grained permissions. You can use the built-in roles or define your own.
  • Some actions are reserved for the owner, including API key management and deleting the business. Deleting a business also revokes its active API keys.
  • Members join by email invitation, and an owner can remove a member at any time.
  • A suspended business cannot be accessed through the app or the API.

Ledger integrity and audit trail

Posted entries cannot be edited or deleted, and every change in a business is recorded with who made it, when and from where.

  • An entry must balance, with total debits equal to total credits, before it can be saved.
  • Posted entries are corrected with a reversal entry. An owner may opt in to returning entries to draft (it is off by default), and every such action is recorded.
  • Lock dates block new, changed, posted or reversed entries in closed periods, in the app and through the API.
  • Opening, closing and reversal entries are created by the system, not typed by hand. Read more in the year-end closing guide.
  • The audit trail stores the action, the user or API key, the IP address, the browser, the time and the changed fields with old and new values.
  • When our support staff sign in as a user to help with a problem, that access expires after one hour and is recorded in the audit log.

Infrastructure, storage and payments

Traffic is encrypted with HTTPS, uploaded documents stay in private storage, and payment data never includes your card number.

  • ledgeriano.com and api.ledgeriano.com are served over HTTPS (TLS). Responses include security headers such as X-Content-Type-Options: nosniff and a strict referrer policy.
  • Entry attachments and payment receipts are stored in private storage and are served only through authenticated requests to people with access.
  • The service runs in production mode with debugging turned off. Unexpected errors show a short reference code instead of internal details.
  • The operators back up the database and file storage.
  • We never receive card numbers. Crypto payments go through NowPayments, and their payment notifications are verified with an HMAC-SHA512 signature before any credits are added.
  • Bank transfer payments add credits only after an administrator has reviewed the transfer proof.

How long operational logs are kept

Logs help with debugging and security investigations, but they should not live forever. A scheduled job deletes them on a fixed timetable.

RecordKept for
API request logs (method, path, status, IP, duration)90 days
Webhook delivery logs (payload, response status)30 days
Workflow run history180 days
Expired session tokensRemoved about one day after they expire

Your accounting data and its audit trail are kept for as long as the business exists. The privacy policy explains retention in full.

Shared responsibility

Six habits that keep your books safer

We secure the platform. These settings are in your hands.

  • Turn on two-factor authentication, especially for business owners.
  • Give each member the smallest role that lets them do their job, and remove members who leave.
  • Create a separate API key for each integration, prefer read-only keys, and set an expiry date.
  • Keep API keys in a secret manager or server environment variables, never in front-end code or a public repository. Rotate a key if it may have been exposed.
  • Verify every webhook signature and reject messages with an old timestamp.
  • Review the audit trail and your active sessions from time to time.
Responsible disclosure

Found a vulnerability? Tell us first

If you believe you have found a security issue in Ledgeriano, email our security team. We welcome reports from customers and independent researchers.

Email the security teamsecurity@ledgeriano.com

Test only with accounts and data you own. We will confirm that we received your report, keep you informed while we work on it and tell you when it is fixed. We do not currently run a paid bug bounty program.

Please include

  • A description of the issue and its possible impact
  • The affected URL or API endpoint
  • Steps to reproduce, with requests and responses if possible
  • How we can reach you for follow-up questions

Please do not

  • Access, change or delete data that belongs to other customers
  • Run denial-of-service tests, spam or social engineering against our staff or users
  • Publish details before we have had a reasonable time to fix the issue

Keep your group's books in a ledger built for control

Create an account, turn on two-factor sign-in and invite your team with the right roles. New accounts receive free credits.