Virtru Private Keystore (for Google Workspace CSE) Log & Error Reference
Table of Contents
- Viewing Container Logs
- Log File Paths
- Downloading & Compressing Logs
- Log Rotation Configuration
- Exporting Logs to a SIEM
- Filtering for Errors
- Enable Debug Logging
- HTTP API Error Codes
- JWT / Authentication Errors
- Configuration / Startup Errors
- S/MIME Errors
- VPK Communication Errors
- Upstream Service Errors
- Getting Help
Viewing Container Logs
Virtru Private Keystore (for Google Workspace CSE) outputs logs to stdout in JSON format using log4js. Both Docker and Podman provide commands to view these logs, displaying the stdout (standard output) and stderr (standard error) streams from the running container.
Basic Commands
| Action | Docker | Podman | Kubernetes |
|---|---|---|---|
| View logs | docker logs <container_id> |
podman logs <container_id> |
kubectl logs <pod> -n <namespace> |
| Last 100 lines | docker logs --tail 100 <container_id> |
podman logs --tail 100 <container_id> |
kubectl logs --tail=100 <pod> -n <namespace> |
| Follow in real-time | docker logs -f <container_id> |
podman logs -f <container_id> |
kubectl logs -f <pod> -n <namespace> |
| With timestamps | docker logs --timestamps <container_id> |
podman logs --timestamps <container_id> |
(timestamps included by default) |
| Last 1 hour | docker logs --since=1h <container_id> |
podman logs --since=1h <container_id> |
kubectl logs --since=1h <pod> -n <namespace> |
| Previous instance | (use log file path) | (use log file path) | kubectl logs --previous <pod> -n <namespace> |
Log File Paths
Docker
Docker stores logs in a specific path on the host machine:
/var/lib/docker/containers/<containerID>/<containerID>-json.log
Each container has its own directory, and log files are saved as JSON.
Podman
Podman allows you to configure a custom log path using the --log-opt parameter:
podman run \ --log-opt path=/var/log/cse-v<version>.log \ ...
This allows you to specify a custom log location, which is useful for centralized log storage and management.
Install Script Default Paths
When using the Virtru install script, files are organized in:
/var/virtru/cse/ ├── cse.env # Environment configuration ├── secrets.json # Secret keys (standalone mode) ├── server.cert # SSL certificate ├── server.key # SSL private key └── run.sh # Docker run script
Kubernetes
Logs are managed by the container runtime and accessible via kubectl logs. For persistent storage, configure a logging sidecar or external log aggregation.
Downloading & Compressing Logs
Export Logs to a File
Docker:
docker logs <container_id> > cse-logs.txt 2>&1
Podman:
podman logs <container_id> > cse-logs.txt 2>&1
Kubernetes:
kubectl logs <pod> -n <namespace> > cse-logs.txt
Transfer Logs from Remote Host
Use scp or other file transfer tools to download log files:
scp user@remote_host:/path/to/cse-logs.txt /local/path/
Compress Logs
Logs can grow quite large. Compressing them makes it easier to store and transfer:
Docker:
docker logs <container_id> 2>&1 | gzip > cse-logs.gz
Podman:
podman logs <container_id> 2>&1 | gzip > cse-logs.gz
Extract compressed logs:
gunzip cse-logs.gz
Log Rotation Configuration
Log rotation prevents container logs from consuming too much disk space.
Docker Log Rotation
Configure log rotation as part of the container setup:
docker run --detach \ --env-file ./cse.env \ -p 443:9000 \ -v /var/virtru/cse/server.cert:/run/secrets/server.cert \ -v /var/virtru/cse/server.key:/run/secrets/server.key \ --restart unless-stopped \ --log-opt max-size=100m \ --log-opt max-file=10 \ --name cse-v<version> \ containers.virtru.com/cse:v<version>
| Option | Description |
|---|---|
--log-opt max-size=100m |
Limits each log file to 100MB |
--log-opt max-file=10 |
Keeps a maximum of 10 log files, discarding oldest |
Podman Log Rotation
Configure log rotation with custom log path:
podman run --detach \ --env-file ./cse.env \ -p 443:9000 \ -v /var/virtru/cse/server.cert:/run/secrets/server.cert \ -v /var/virtru/cse/server.key:/run/secrets/server.key \ --restart unless-stopped \ --name cse-v<version> \ --log-opt path=/var/log/cse-v<version>.log \ containers.virtru.com/cse:v<version>
For more information on Docker logging drivers, see: Docker Logging Configuration
Exporting Logs to a SIEM
Logs can be forwarded to a remote syslog server for centralized monitoring and analysis.
Docker Syslog Driver
Configure the container to send logs directly to a remote syslog server:
docker run --detach \ --env-file ./cse.env \ -p 443:9000 \ -v /var/virtru/cse/server.cert:/run/secrets/server.cert \ -v /var/virtru/cse/server.key:/run/secrets/server.key \ --restart unless-stopped \ --name cse-v<version> \ --log-driver syslog \ --log-opt syslog-address=tcp://192.168.10.15:10514 \ containers.virtru.com/cse:v<version>
| Option | Description |
|---|---|
--log-driver syslog |
Use syslog logging driver |
--log-opt syslog-address=tcp://192.168.10.15:10514 |
Remote syslog server address and port |
Host-Level Syslog Forwarding
Alternatively, forward all host syslog entries (including container logs) to a remote server.
Note: This will include additional host events beyond container logs.
Edit /etc/rsyslog.d/50-default.conf:
nano /etc/rsyslog.d/50-default.conf
Add at the top:
*.* action(type="omfwd" target="192.168.10.15" port="10514" protocol="tcp" action.resumeRetryCount="100" queue.type="linkedList" queue.size="10000")
| Parameter | Description |
|---|---|
target |
Remote syslog server IP |
port |
Remote syslog server port |
protocol |
Transport protocol (tcp/udp) |
action.resumeRetryCount |
Number of retry attempts |
queue.size |
Number of entries to queue before discarding |
Important: Due to the nature of TCP, if the remote syslog server is unavailable, entries will be blocked and discarded if a retry queue is not configured.
Restart rsyslog after making changes:
sudo systemctl restart rsyslog
Filtering for Errors
Use these patterns to filter logs for specific error types.
Useful Grep Patterns
| Pattern | What It Finds |
|---|---|
grep -i "error" |
All errors |
grep -i "fatal" |
Fatal startup errors |
grep "ForbiddenError" |
Access denied errors |
grep "UnauthorizedError" |
Authentication failures |
grep "BadRequestError" |
Invalid request errors |
grep "401\|403" |
Auth/access failures |
grep -i "jwt\|token" |
JWT/token issues |
grep -i "cks\|rewrap" |
VPK communication |
grep -i "smime\|privatekey" |
S/MIME operations |
Example: Filter Errors from Docker
docker logs cse 2>&1 | grep -iE "(error|fatal|failed)"
Example: Parse JSON Logs with jq
docker logs cse 2>&1 | jq 'select(.level == "ERROR")'
Enable Debug Logging
For more verbose output when troubleshooting, set this environment variable:
| Variable | Value | Description |
|---|---|---|
LOG_LEVEL |
DEBUG |
Detailed application logs |
Available levels: OFF, FATAL, ERROR, WARN, INFO (default), DEBUG, TRACE, ALL
Note: Debug logging increases log volume significantly. Disable after troubleshooting is complete.
HTTP API Error Codes
Core Endpoints
| Endpoint | Method | Success | Error Codes |
|---|---|---|---|
/status |
GET | 200 | 500 |
/certs |
GET | 200 | 500 |
/wrap |
POST | 200 | 400, 401, 403, 500 |
/unwrap |
POST | 200 | 400, 401, 403, 500 |
/rewrap |
POST | 200 | 400, 401, 403, 500 |
/digest |
POST | 200 | 400, 401, 403, 500 |
/privilegedwrap |
POST | 200/201 | 400, 401, 403, 500 |
/privilegedunwrap |
POST | 200 | 400, 401, 403, 500 |
S/MIME Endpoints (Gmail)
| Endpoint | Method | Success | Error Codes |
|---|---|---|---|
/privatekeydecrypt |
POST | 200 | 400, 401, 403, 500 |
/privilegedprivatekeydecrypt |
POST | 200 | 400, 401, 403, 500 |
/privatekeysign |
POST | 200 | 400, 401, 403, 500 |
HTTP Status Codes
| Status | Meaning | Common Cause |
|---|---|---|
200 |
Success | Request completed successfully |
201 |
Created | Resource created (privilegedwrap) |
400 |
Bad Request | Invalid request body, malformed JSON, invalid algorithm |
401 |
Unauthorized | Invalid or missing authentication token |
403 |
Forbidden | Access denied - policy violation, invalid role, blocked |
500 |
Internal Server Error | Unexpected server error |
Error Classes
| Error Class | HTTP Status | Description |
|---|---|---|
ForbiddenError |
403 | Access denied - policy violation or insufficient permissions |
UnauthorizedError |
401 | Authentication failed - invalid or missing token |
BadRequestError |
400 | Invalid request - malformed input, invalid parameters |
MalformedAuthorizationHeaderError |
400 | Authorization header format invalid |
InternalServerError |
500 | Unexpected internal error |
JWT / Authentication Errors
Token Validation Errors
| Error Pattern | Meaning | Resolution |
|---|---|---|
Invalid or missing email in JWT |
Token lacks email claim | Check IdP configuration, ensure email claim included |
Invalid or missing resource_name in JWT |
Missing resource identifier | Check authorization token generation |
Invalid or missing kacls_url in JWT |
URL mismatch | Verify JWT_KACLS_URL matches token's kacls_url claim |
Invalid or missing role in JWT |
Role missing or invalid | Check authorization token has required role |
Unverified issuer |
Issuer not in allowed list | Add issuer to JWKS_AUTHN_ISSUERS or JWKS_AUTHZ_ISSUERS
|
Illegal alg value from token |
Unsupported algorithm | Use RS256 |
Missing authorization or authentication token |
Required tokens not provided | Include both authn and authz JWT tokens |
Users in authorization and authentication tokens do not match |
Token user mismatch | Ensure same user identity in both tokens |
Role Requirements
| Endpoint | Required Roles |
|---|---|
/wrap |
writer, upgrader
|
/unwrap |
reader, writer
|
/rewrap |
migrator |
/privatekeydecrypt |
decrypter |
/privatekeysign |
signer |
/digest |
verifier |
/privilegedunwrap |
privilegedunwrap (takeout claim) |
/privilegedwrap |
privilegedwrap |
IdP Configuration
Google (Default):
| Setting | Value |
|---|---|
| Authn Issuer | https://accounts.google.com |
| Authn JWKS | https://www.googleapis.com/oauth2/v3/certs |
Okta:
| Setting | Value |
|---|---|
| Authn Issuer | https://<domain>/oauth2/default |
| Authn JWKS | https://<domain>/oauth2/default/v1/keys |
Configuration / Startup Errors
Missing Environment Variables
| Error Message | Resolution |
|---|---|
Missing environment variable |
Set the required environment variable |
Must specify JWT_KACLS_URL |
Set JWT_KACLS_URL to your CSE's public URL |
Missing HMAC token ID/secret! |
Set HMAC_TOKEN_ID and HMAC_TOKEN_SECRET
|
Secret Key Errors (Standalone Mode)
| Error Message | Meaning | Resolution |
|---|---|---|
SECRET_KEYS_PATH must be defined |
No secret key config | Set SECRET_KEYS_PATH or SECRET_KEY
|
The Secret Key is Missing from the Secrets File |
secrets.json missing key | Add secret to secrets.json
|
Secret Key not found at Path! |
File doesn't exist | Create secrets.json at specified path |
Detected a corrupt secrets file |
Invalid JSON format | Fix JSON syntax in secrets.json
|
Secrets File or Secret Key has been corrupted! |
Empty or invalid content | Regenerate secrets file |
Base64 Encoding Errors
| Error Message | Meaning | Resolution |
|---|---|---|
Error parsing base64 encoded map |
Invalid base64 JSON | Re-encode the JSON map properly |
Encoding Example:
# JWKS_AUTHN_ISSUERS
echo '{ "https://accounts.google.com": "https://www.googleapis.com/oauth2/v3/certs" }' | base64 -w 0
# JWT_AUD
echo '{ "authn": "<client-id>", "authz": "cse-authorization" }' | base64 -w 0S/MIME Errors
Algorithm Errors
| Error Message | Meaning | Resolution |
|---|---|---|
is not a supported Decryption Algorithm |
Unsupported decrypt algorithm | Use supported algorithm (see below) |
is not a supported Signature Algorithm |
Unsupported sign algorithm | Use supported algorithm (see below) |
The algorithm in the request does not match |
Invalid algorithm | Check algorithm spelling/format |
Supported Decryption Algorithms:
RSA/ECB/PKCS1PaddingRSA/ECB/OAEPwithSHA-1andMGF1PaddingRSA/ECB/OAEPwithSHA-256andMGF1PaddingRSA/ECB/OAEPwithSHA-512andMGF1Padding
Supported Signing Algorithms:
SHA1withRSASHA256withRSASHA1withRSA/PSSSHA256withRSA/PSSSHA512withRSA/PSS
SPKI Hash Errors
| Error Message | Meaning | Resolution |
|---|---|---|
SPKI Hash does not match |
Hash mismatch | Verify private key matches expected SPKI hash |
The SPKI Hash Algorithm in the request does not match |
Invalid hash algorithm | Use SHA-256 |
Digest Errors
| Error Message | Meaning | Resolution |
|---|---|---|
The digest length must be 20 bytes for SHA-1 |
Wrong digest length | Provide 20-byte digest |
The digest length must be 32 bytes for SHA-256 |
Wrong digest length | Provide 32-byte digest |
The digest length must be 64 bytes for SHA-512 |
Wrong digest length | Provide 64-byte digest |
RSA/PSS Salt Length must exist |
Missing salt length | Include salt length in request |
VPK Communication Errors
When operating with VPK (Virtru Private Keystore for Virtru Solutions), CSE communicates with VPK for key operations.
| Error Pattern | Meaning | Resolution |
|---|---|---|
CKSRequestError |
Request to VPK failed | Check VPK connectivity, authentication |
401 from VPK |
VPK authentication failed | Verify HMAC credentials |
409 from VPK |
Key not found on VPK | Verify key exists, check fingerprint |
500 from VPK |
VPK internal error | Check VPK logs |
| Connection refused | VPK unreachable | Verify VPK URL, network connectivity |
| Certificate errors | TLS issue | Check VPK SSL certificate, CA trust |
Upstream Service Errors
ACM Errors
These errors originate from Virtru's Access Control Manager (ACM):
| Error | Status | Meaning | Resolution |
|---|---|---|---|
UnauthorizedPolicyAccessError |
403 | Policy doesn't exist or user not authorized | Check policy exists, user has access |
InvalidPermissionsError |
403 | User lacks required permissions | Verify user permissions |
BlockedPlatformError |
403 | Platform is blocked | Check platform restrictions |
PreconditionsUnmetError |
412 | Requirements not met (e.g., user needs public key) | User may need to set up Secure Reader |
TooManyRequestsError |
429 | Rate limited | Reduce request frequency |
Getting Help
If you're unable to resolve an issue using this guide, please contact Virtru Support:
Virtru Support Portal: support.virtru.com
When contacting support, please include:
- CSE version
- Deployment type (Docker, Podman, Kubernetes)
- Relevant log output (filtered for errors)
- Steps to reproduce the issue
- Any recent configuration changes
Related Documentation:
- Virtru Private Keystore (VPK) Log & Error Reference - For VPK-specific errors