Skip to main content

Audit Logging

Yopass can emit a structured audit log recording every security-relevant event — secret creation, access, deletion, and authentication — without ever logging encrypted content. The log is designed for compliance requirements such as SOC 2, ISO 27001, and GDPR data-access accountability.

Requires a valid license. Audit logging is a premium feature gated behind --license-key.


Enabling audit logging​

yopass-server \
--license-key "your-license-key" \
--audit-log

By default, audit records are written to stdout as NDJSON (one JSON object per line), separate from the regular application log. To write to a dedicated file instead:

yopass-server \
--license-key "your-license-key" \
--audit-log \
--audit-log-file /var/log/yopass/audit.log

Flags​

FlagEnv varDefaultDescription
--audit-logAUDIT_LOGfalseEnable audit logging (requires valid license)
--audit-log-fileAUDIT_LOG_FILE—Write audit log to this file path. When unset, records go to stdout.

Log format​

Each event is a single JSON object terminated by a newline (NDJSON). Fields are only emitted when they are relevant to the event — optional fields are omitted rather than set to null or empty.

Fields​

FieldTypeAlways presentDescription
timestampstring (RFC3339Nano, UTC)yesWhen the event occurred
eventstringyesEvent type (see Events)
outcomestringyessuccess, failure, or denied
client_ipstringyesReal client IP, respecting --trusted-proxies
secret_idstringnoFirst 12 hexadecimal characters of the SHA-256 hash of the secret or file ID
user_emailstringnoAuthenticated user's email (OIDC sessions only)
user_subjectstringnoAuthenticated user's OIDC subject claim
one_timeboolnoWhether the secret was configured for one-time access
expiration_secondsnumbernoTTL in seconds at creation time
require_authboolnoWhether the secret requires OIDC authentication to access
errorstringnoHuman-readable reason for failure or denied outcomes

Privacy note: Encrypted secret content is never written to the audit log — only a hashed ID and metadata are recorded.

Example records​

Successful secret creation:

{"timestamp":"2026-04-09T12:00:01.123456789Z","event":"secret.created","outcome":"success","client_ip":"203.0.113.42","secret_id":"3a128f193823","one_time":true,"expiration_seconds":3600,"require_auth":false,"user_email":"[email protected]","user_subject":"auth0|abc123"}

Access denied (unauthenticated):

{"timestamp":"2026-04-09T12:01:00.000000001Z","event":"secret.accessed","outcome":"denied","client_ip":"198.51.100.7","secret_id":"3a128f193823","require_auth":true,"error":"authentication required"}

Successful login:

{"timestamp":"2026-04-09T12:00:00.500000000Z","event":"auth.callback_success","outcome":"success","client_ip":"203.0.113.42","user_email":"[email protected]","user_subject":"auth0|abc123"}

Events​

Secret events​

EventTriggered byOutcomes
secret.createdPOST /create/secretsuccess, failure, denied
secret.accessedGET /secret/{key}success, failure, denied
secret.deletedDELETE /secret/{key}success, failure
secret.receipt_checkedGET /secret/{key}/receipt (see Read Receipts)success, failure, denied

File events​

EventTriggered byOutcomes
file.uploadedPOST /create/filesuccess, failure, denied
file.downloadedGET /file/{key}success, failure, denied
file.deletedDELETE /file/{key}success, failure

Auth events​

EventTriggered byOutcomes
auth.callback_successOIDC callback (successful login)success
auth.callback_failedOIDC callback (rejected login, including state/code exchange failures)failure, denied
auth.logoutPOST /auth/logoutsuccess, denied

Outcomes:

  • success — operation completed normally
  • failure — operation failed (validation error, database error, not found)
  • denied — operation was rejected due to missing or insufficient authentication

HTTP access logs​

Regular HTTP access logs are redacted regardless of whether licensed audit logging is enabled. The uri field contains the route template, such as /secret/{key}/status. Only routes with a {key} parameter include secret_id, which contains the same truncated SHA-256 hash used by audit logs. Routes such as /config and /auth/callback omit that field.

Raw identifiers and URL query strings are omitted, including OIDC callback codes and state parameters. Unmatched requests log unmatched; requests handled by the static-file fallback log / without the requested filename.

File store errors and cleanup messages in the application log follow the same rule: an identifier inside an S3 request URL or a disk path is replaced with its secret_id hash.

Apply equivalent redaction to reverse proxies, API Gateway access logs, and log collectors: application redaction cannot remove URLs recorded by those systems. Existing logs may still contain usable identifiers until the associated secrets expire or are consumed; restrict access and handle those logs under your credential-exposure policy.


Log rotation​

When writing to a file (--audit-log-file), Yopass does not rotate logs itself. Use your platform's standard tooling:

logrotate (/etc/logrotate.d/yopass-audit):

/var/log/yopass/audit.log {
daily
rotate 90
compress
delaycompress
missingok
notifempty
copytruncate
}

The copytruncate directive truncates the file in place so no SIGHUP or file descriptor hand-off is needed.

systemd with StandardOutput=append:/var/log/yopass/audit.log and journald log rotation handles this automatically for systemd-managed deployments.


Docker Compose example​

services:
yopass:
image: jhaals/yopass:latest
ports:
- "1337:1337"
environment:
MEMCACHED: memcached:11211
LICENSE_KEY: your-license-key
AUDIT_LOG: "true"
volumes:
- ./logs:/var/log/yopass
command: >
yopass-server
--audit-log-file /var/log/yopass/audit.log
depends_on:
- memcached

memcached:
image: memcached

To write to stdout (and let your log collector handle it):

environment:
AUDIT_LOG: "true"
# no AUDIT_LOG_FILE — records go to stdout alongside application logs

Tip: When writing to stdout in a containerized environment, prefix your log shipping filter on "event": to separate audit records from regular application log lines.


Combining with OIDC​

Audit logging is most valuable when combined with OpenID Connect. With OIDC configured, every audit record that involves an authenticated session includes user_email and user_subject, giving you a full identity trail for compliance reviews.

yopass-server \
--license-key "your-license-key" \
--audit-log \
--oidc-issuer "https://accounts.google.com" \
--oidc-client-id "123456789-abc.apps.googleusercontent.com" \
--oidc-client-secret "GOCSPX-…" \
--oidc-redirect-url "https://yopass.example.com/auth/callback"

Without OIDC, user_email and user_subject are omitted from all audit records.