Skip to main content
CCDigital uses environment variables for all runtime configuration. This approach enables flexible deployment across different environments without modifying application code.

Configuration Overview

All configuration is loaded through application.properties, which maps environment variables to Spring Boot properties using the ${VAR_NAME} syntax. Variables are organized by functional area.

Required Variables

App and Server Configuration

APP_NAME
string
default:"CCDigital"
Logical name of the application displayed in logs and Spring context.
SERVER_PORT
integer
default:"8080"
HTTP port where Spring Boot will listen for incoming requests.
SERVER_SESSION_TIMEOUT
duration
default:"5m"
Maximum session inactivity timeout. Accepts duration format (e.g., 30m, 1h).

Database Configuration

DB_URL
string
required
Complete JDBC connection string for MySQL database.Format: jdbc:mysql://<HOST>:<PORT>/<DATABASE_NAME>?<PARAMETERS>Example: jdbc:mysql://localhost:3306/ccdigital?useSSL=false&serverTimezone=UTC
DB_USERNAME
string
required
Database user with full permissions on the application database.
DB_PASSWORD
string
required
Password for the database user.
JPA_DDL_AUTO
string
default:"none"
Hibernate schema management strategy.Options:
  • none: No schema management (production)
  • validate: Validate schema matches entities
  • update: Update schema automatically (development only)
  • create: Drop and recreate schema (testing only)
Use none in production. Schema changes should be managed through migrations.
JPA_SHOW_SQL
boolean
default:"true"
Enable SQL query logging. Set to false in production for performance.
JPA_FORMAT_SQL
boolean
default:"true"
Pretty-print SQL queries in logs. Set to false in production.

File Storage Configuration

CCDIGITAL_FS_BASE_PATH
string
required
Absolute directory path where document files are stored.This directory must:
  • Exist and be writable by the application process
  • Have sufficient disk space for document storage
  • Be backed up regularly
Maps to:
  • ccdigital.fs.base-path
  • app.user-files-base-dir
Example: /home/ccdigital/CCDigitalBlock/storage
APP_USER_FILES_LEGACY_BASE_DIR
string
Optional legacy base directory for migrated files. Used for backward compatibility.

ACA-Py / Indy Configuration

ACA-Py (Aries Cloud Agent Python) is used for Hyperledger Indy credential verification during user authentication.
ACAPY_VERIFIER_ADMIN_URL
string
required
Admin API endpoint of the ACA-Py verifier agent.Example: http://localhost:8021
ACAPY_HOLDER_ADMIN_URL
string
required
Admin API endpoint of the ACA-Py holder agent.Example: http://localhost:8031
ACAPY_CRED_DEF_ID
string
required
Credential definition ID used for proof verification.Example: WgWxqztrNooG92RXvxSTWv:3:CL:20:tag
ACAPY_PROOF_POLL_INTERVAL_MS
integer
default:"1000"
Polling interval in milliseconds when waiting for proof presentation completion.
ACAPY_PROOF_POLL_TIMEOUT_MS
integer
default:"20000"
Maximum timeout in milliseconds for proof presentation.
INDY_ISSUER_ADMIN_URL
string
Issuer agent admin URL. Defaults to ACAPY_VERIFIER_ADMIN_URL if not set.
INDY_HOLDER_ADMIN_URL
string
Holder agent admin URL for administrative operations. Defaults to ACAPY_HOLDER_ADMIN_URL if not set.
INDY_HOLDER_CONNECTION_ID
string
default:"auto"
Connection ID for holder agent. Use auto to automatically find active connection by label.
INDY_HOLDER_LABEL
string
required
Label used to identify the holder connection when INDY_HOLDER_CONNECTION_ID is set to auto.
INDY_CRED_DEF_ID
string
Credential definition ID for Indy operations. Defaults to ACAPY_CRED_DEF_ID if not set.
INDY_ADMIN_API_KEY
string
API key for securing admin API endpoints (if ACA-Py is configured with API key protection).
INDY_USER_ACCESS_SYNC_ENABLED
boolean
default:"true"
Enable synchronization of user access state to ACA-Py connection metadata.
INDY_USER_ACCESS_SYNC_PATH
string
default:"/connections/{conn_id}/metadata"
API path template for updating connection metadata. {conn_id} is replaced with actual connection ID.

Hyperledger Fabric Configuration

Fabric is used for document audit trail and access event logging on distributed ledger.
FABRIC_WORKDIR
string
required
Working directory containing Fabric client scripts and configuration.Example: /home/ccdigital/fabric-client
FABRIC_NODE_BIN
string
required
Path to Node.js binary used to execute Fabric client scripts.Example: /usr/bin/node or /home/ccdigital/.nvm/versions/node/v18.16.0/bin/node
FABRIC_LIST_DOCS_SCRIPT
string
required
Node.js script that lists documents for a person from the Fabric ledger.Example: list-docs.js
FABRIC_BLOCK_READER_SCRIPT
string
required
Script that reads block details by reference from Fabric ledger.Example: read-block-by-ref.js
FABRIC_RECORD_ACCESS_SCRIPT
string
required
Script that records access events (verification/consultation) to the ledger.Example: record-access-event.js
FABRIC_LIST_ACCESS_SCRIPT
string
required
Script that lists audit events from the ledger (by person or globally).Example: list-access-events.js
FABRIC_SYNC_ALL_SCRIPT
string
required
Script for bulk synchronization of database documents to Fabric ledger.Example: sync-db-to-ledger.js
FABRIC_SYNC_PERSON_SCRIPT
string
required
Script for synchronizing a specific person’s documents to Fabric ledger.Example: sync-person-to-ledger.js

Indy Tools Configuration

INDY_TOOLS_WORKDIR
string
required
Working directory containing Python scripts for credential issuance.Example: /home/ccdigital/indy-tools
INDY_VENV_ACTIVATE
string
required
Command to activate Python virtual environment before running Indy scripts.Example: source /home/ccdigital/indy-tools/venv/bin/activate
INDY_SCRIPT
string
required
Main Python script for credential issuance from database.Example: issue_credentials_from_db.py
EXTERNAL_TOOLS_TIMEOUT_SECONDS
integer
default:"180"
Global timeout for external script execution (Fabric and Indy scripts).

Mail Configuration

SMTP configuration is required for OTP delivery, email verification, and password recovery.
MAIL_HOST
string
required
SMTP server hostname.Examples:
  • Gmail: smtp.gmail.com
  • Office365: smtp.office365.com
MAIL_PORT
integer
required
SMTP server port.Common ports:
  • 587: STARTTLS (recommended)
  • 465: SSL/TLS
  • 25: Unencrypted (not recommended)
MAIL_USERNAME
string
required
SMTP authentication username (usually the email address).
MAIL_PASSWORD
string
required
SMTP authentication password or app-specific password.
For Gmail, you must use an App Password, not your regular account password.
MAIL_SMTP_AUTH
boolean
default:"true"
Enable SMTP authentication.
MAIL_SMTP_STARTTLS_ENABLE
boolean
default:"true"
Enable STARTTLS encryption.
MAIL_SMTP_STARTTLS_REQUIRED
boolean
default:"true"
Require STARTTLS encryption (fail if not available).
FORGOT_PASSWORD_MAIL_FROM
string
required
Sender email address for password recovery emails.Example: [email protected]
MAIL_TEST_CONNECTION
boolean
default:"true"
Test SMTP connection on application startup. Useful for early detection of mail configuration issues.

Security Configuration (Optional)

APP_SECURITY_REQUIRE_HTTPS
boolean
Enforce HTTPS-only access. Enable in production behind reverse proxy.
APP_SECURITY_SIGNED_URLS_SECRET
string
Secret key for signing document access URLs. Generate a strong random string.
APP_SECURITY_SIGNED_URLS_TTL_SECONDS
integer
Time-to-live for signed URLs in seconds.
APP_SECURITY_RATE_LIMIT_ENABLED
boolean
Enable rate limiting on sensitive endpoints.
APP_SECURITY_RATE_LIMIT_WINDOW_SECONDS
integer
Time window for rate limiting in seconds.
APP_SECURITY_RATE_LIMIT_MAX_REQUESTS_PER_WINDOW
integer
Maximum requests allowed per time window.

Login OTP Configuration (Optional)

APP_SECURITY_LOGIN_OTP_CODE_LENGTH
integer
Length of OTP codes for login second factor.
APP_SECURITY_LOGIN_OTP_CODE_TTL_MINUTES
integer
Time-to-live for login OTP codes in minutes.
APP_SECURITY_LOGIN_OTP_MAX_ATTEMPTS
integer
Maximum OTP verification attempts before lockout.
APP_SECURITY_LOGIN_OTP_RESEND_COOLDOWN_SECONDS
integer
Cooldown period between OTP resend requests.
APP_SECURITY_LOGIN_OTP_MAIL_FROM
string
Sender email address for login OTP emails.

Registration Email OTP Configuration (Optional)

APP_SECURITY_REGISTER_EMAIL_OTP_CODE_LENGTH
integer
Length of OTP codes for email verification during registration.
APP_SECURITY_REGISTER_EMAIL_OTP_CODE_TTL_MINUTES
integer
Time-to-live for registration OTP codes in minutes.
APP_SECURITY_REGISTER_EMAIL_OTP_MAX_ATTEMPTS
integer
Maximum verification attempts during registration.
APP_SECURITY_REGISTER_EMAIL_OTP_RESEND_COOLDOWN_SECONDS
integer
Cooldown period between registration OTP resend requests.
APP_SECURITY_REGISTER_EMAIL_OTP_MAIL_FROM
string
Sender email address for registration verification emails.

Password Recovery Configuration (Optional)

APP_SECURITY_FORGOT_PASSWORD_CODE_LENGTH
integer
Length of password recovery codes.
APP_SECURITY_FORGOT_PASSWORD_CODE_TTL_MINUTES
integer
Time-to-live for password recovery codes in minutes.
APP_SECURITY_FORGOT_PASSWORD_MAX_ATTEMPTS
integer
Maximum password recovery verification attempts.
APP_SECURITY_FORGOT_PASSWORD_RESEND_COOLDOWN_SECONDS
integer
Cooldown period between password recovery code resend requests.

TOTP (Authenticator App) Configuration (Optional)

APP_SECURITY_TOTP_ISSUER
string
Issuer identifier for TOTP tokens (displayed in authenticator apps).
APP_SECURITY_TOTP_ISSUER_NAME
string
Human-readable issuer name for TOTP.
APP_SECURITY_TOTP_DIGITS
integer
Number of digits in TOTP codes (typically 6).
APP_SECURITY_TOTP_CODE_DIGITS
integer
Alias for TOTP_DIGITS.
APP_SECURITY_TOTP_PERIOD_SECONDS
integer
TOTP code refresh period in seconds (typically 30).
APP_SECURITY_TOTP_WINDOW_STEPS
integer
Number of time steps to check for TOTP validation (allows clock drift).
APP_SECURITY_TOTP_SECRET_BYTES
integer
Size of TOTP secret in bytes.

Environment Template

Use this template to create your environment configuration file:
# App and Server
export APP_NAME='CCDigital'
export SERVER_PORT='8080'
export SERVER_SESSION_TIMEOUT='30m'

# Database
export DB_URL='jdbc:mysql://localhost:3306/ccdigital?useSSL=false&serverTimezone=UTC'
export DB_USERNAME='ccdigital_user'
export DB_PASSWORD='your_secure_password'
export JPA_DDL_AUTO='none'
export JPA_SHOW_SQL='false'
export JPA_FORMAT_SQL='false'

# File Storage
export CCDIGITAL_FS_BASE_PATH='/var/ccdigital/storage'

# ACA-Py / Indy
export ACAPY_VERIFIER_ADMIN_URL='http://localhost:8021'
export ACAPY_HOLDER_ADMIN_URL='http://localhost:8031'
export ACAPY_CRED_DEF_ID='WgWxqztrNooG92RXvxSTWv:3:CL:20:tag'
export ACAPY_PROOF_POLL_INTERVAL_MS='1000'
export ACAPY_PROOF_POLL_TIMEOUT_MS='20000'

export INDY_HOLDER_LABEL='holder-wallet'
export INDY_HOLDER_CONNECTION_ID='auto'
export INDY_USER_ACCESS_SYNC_ENABLED='true'
export INDY_USER_ACCESS_SYNC_PATH='/connections/{conn_id}/metadata'

# Fabric
export FABRIC_WORKDIR='/opt/fabric-client'
export FABRIC_NODE_BIN='/usr/bin/node'
export FABRIC_LIST_DOCS_SCRIPT='list-docs.js'
export FABRIC_BLOCK_READER_SCRIPT='read-block-by-ref.js'
export FABRIC_RECORD_ACCESS_SCRIPT='record-access-event.js'
export FABRIC_LIST_ACCESS_SCRIPT='list-access-events.js'
export FABRIC_SYNC_ALL_SCRIPT='sync-db-to-ledger.js'
export FABRIC_SYNC_PERSON_SCRIPT='sync-person-to-ledger.js'

# Indy Tools
export INDY_TOOLS_WORKDIR='/opt/indy-tools'
export INDY_VENV_ACTIVATE='source /opt/indy-tools/venv/bin/activate'
export INDY_SCRIPT='issue_credentials_from_db.py'
export EXTERNAL_TOOLS_TIMEOUT_SECONDS='180'

# Mail
export MAIL_HOST='smtp.gmail.com'
export MAIL_PORT='587'
export MAIL_USERNAME='[email protected]'
export MAIL_PASSWORD='your-app-password'
export MAIL_SMTP_AUTH='true'
export MAIL_SMTP_STARTTLS_ENABLE='true'
export MAIL_SMTP_STARTTLS_REQUIRED='true'
export FORGOT_PASSWORD_MAIL_FROM='[email protected]'
export MAIL_TEST_CONNECTION='true'
Never commit environment files containing secrets to version control. Use .gitignore to exclude them.

Loading Environment Variables

Option 1: Environment File

Create an environment file (e.g., ccdigital.env) and source it before starting:
source ccdigital.env
java -jar ccdigital.jar

Option 2: Systemd Service

For systemd services, use EnvironmentFile directive:
[Service]
EnvironmentFile=/etc/ccdigital/ccdigital.env
ExecStart=/usr/bin/java -jar /opt/ccdigital/ccdigital.jar

Option 3: Docker

Pass environment variables using --env-file flag:
docker run --env-file ccdigital.env -p 8080:8080 ccdigital:latest

Validation

Verify your configuration by checking application logs during startup:
1

Check Database Connection

Look for successful Hibernate initialization messages.
2

Verify File Storage Path

Ensure the base path exists and is writable. Check for FileStorageService initialization logs.
3

Test Mail Configuration

If MAIL_TEST_CONNECTION=true, the application will test SMTP connection on startup.
4

Validate External Tools

Check that Fabric and Indy script paths are accessible and executable.

Build docs developers (and LLMs) love