Skip to content

Production Hardening — Security Checklist for Xferity Deployments

Production hardening for Xferity means eliminating insecure configuration patterns and reducing the attack surface before live partner exchange begins.

This page covers what to do and what to check before treating a deployment as production-ready.

Set this in your global configuration:

security:
hardened_mode: true

Hardened mode causes Xferity to reject the following at startup:

  • plaintext credential values in sensitive configuration fields (passwords, passphrases, key material)
  • Vault TLS with insecure_skip_verify=true
  • state.postgres.sslmode=disable
  • partner configurations with insecure_skip_verify=true (FTPS, AS2)
  • UI startup without authentication configuration
  • UI startup without TLS when required authentication is absent

Hardened mode turning on is the most impactful single configuration change for a production deployment. Enable it early in the setup process, not after go-live.

Before production, audit all configuration files and replace plaintext sensitive values with secret references:

# Bad - plaintext
sftp:
password: mypassword123
# Good - secret reference
sftp:
password: env:PARTNER_SFTP_PASSWORD

Supported secret reference types:

  • env:VAR_NAME — environment variable
  • file:/path/to/secret — file content
  • vault:path#field — HashiCorp Vault
  • aws-sm:secret-id#field — AWS Secrets Manager
  • azure-kv:secret-name — Azure Key Vault
  • local-vault:key — local encrypted vault (Postgres mode)

Never store private keys, passphrases, API tokens, or database passwords as plaintext in config files checked into version control.

In Postgres-backed deployments, require TLS for database connections:

state:
backend: postgres
postgres:
sslmode: require # minimum; use verify-full for stricter trust

sslmode=disable is rejected in hardened mode. Use require, verify-ca, or verify-full for production.

If the Web UI is enabled, configure authentication:

auth:
mode: local # or oidc
local:
username: admin
password_ref: env:UI_ADMIN_PASSWORD

Or OIDC:

auth:
mode: oidc
oidc:
enabled: true
issuer_url: https://auth.example.com
client_id: xferity
client_secret: env:OIDC_CLIENT_SECRET
redirect_url: https://xferity.example.com/auth/callback

In hardened mode, starting the UI without authentication configured fails startup.

For production, enable TLS on the UI:

ui:
enabled: true
host: 0.0.0.0
port: 8443
tls_cert_path: /etc/xferity/certs/server.pem
tls_key_path: /etc/xferity/certs/server-key.pem

Alternatively, terminate TLS at a reverse proxy (Nginx, Caddy, Traefik) and forward HTTP internally. In that case, configure ui.trust_proxy_headers=true to correctly extract client IP from X-Forwarded-For.

The runtime filesystem layout contains sensitive material. Apply least-privilege permissions:

PathContentRecommended permissions
Config and flow filesconfigurationread-only to the service user
Partner definitionsendpoint config with partial secretsread-only to the service user
Key and cert filesprivate keys and certificates600 or 640, owner = service user
Audit filestransfer evidenceappend-only where possible
State fileshistory, idempotency recordsread-write to service user only
Storage directoriesfile contentsread-write to service user

Do not run Xferity as root.

For SFTP flows in high-security environments, restrict SSH ciphers and key exchange algorithms:

security:
ssh_ciphers:
- aes256-gcm@openssh.com
- chacha20-poly1305@openssh.com
ssh_kex_algorithms:
- curve25519-sha256
- diffie-hellman-group16-sha512

Leaving these empty uses Go’s SSH library defaults, which are generally secure but include a wider algorithm set.

Configure HTTP and AS2 rate limiting to reduce abuse exposure:

http:
rate_limit:
enabled: true
requests_per_second: 10
burst: 30
as2_requests_per_second: 5
as2_burst: 20
as2_per_partner: true

AS2 per-partner rate limiting (as2_per_partner=true) applies the limit independently per partner AS2 ID, which is the most relevant protection for AS2 inbound.

/metrics is behind authenticated admin access. Do not expose it publicly without authentication.

If your Prometheus setup cannot send auth headers, use a sidecar or network policy to restrict /metrics to the monitoring host.

Before enabling production scheduled flows:

  1. check the security posture page for Active Findings
  2. resolve or suppress all findings with documented justification
  3. verify no certificate expiry findings are present
  4. confirm all secret references resolve correctly (use xferity diag)
  5. confirm Partner Crypto Policy shows all required roles as healthy
  6. confirm hardened mode is on and no startup warnings remain

Keep all configuration, flow definitions, and partner definitions under version control:

  • enables audit history of changes
  • enables rollback when a bad config change causes failures
  • enables change review before production promotion

Never modify production configuration directly without a version-controlled change record.