version: 2024-02
Prerequisites |
---|
See how Enterprise Server will be deployed for your company. |
The Enterprise Server is a simplified deployment containing the FlowCrypt EAP, EKM, FES, and WKD applications in one combined executable. The full architecture described in the Deployment Overview guide is quite cumbersome for smaller clients, so this Enterprise Server helps to deploy as a single application. Please see the individual applications for information on each one, as they also apply to the configuration process of this service.
- Enterprise Admin Panel (EAP)
- Email Key Manager (EKM)
- FlowCrypt External Service (FES)
- Web Key Directory (WKD)
The database-level encryption is preferable, but not mandatory, as we encrypt private keys with AES-256 individually before storing them in the database and decrypting them upon retrieval. The database encryption key for the encryption/decryption process can be either configured for the service directly or retrieved over KMIP or PKCS#11 from your existing Hardware Security Module (HSM) or Key Management System (KMS).
Requirements
You need to ensure all the requirements described in the Enterprise Server Deployment Requirements guide, plus the following:
Type | Requirement |
---|---|
Database | PostgreSQL or CockroachDB for production. H2 for testing & evaluation. Optionally protected by KMIP or PKCS#11. |
Network | The Enterprise Server must be accessible on an internal URL from client devices, with a TLS certificate trusted by the client. The /api/ and /.well-known/ folders must typically also be accessible on the public internet. The service also needs limited external access to the internet to fetch Google JWK for user authentication, and Admin JWKs for Admin Panel authentication if the Admin IdP is accessed over the public internet. |
Distribution and deployment
FlowCrypt Enterprise Server is distributed as a zip file containing:
Filename | Description |
---|---|
flowcrypt-enterprise-server.jar |
Runnable Java JAR |
flowcrypt-enterprise-server.properties |
Default config for Enterprise Server |
flowcrypt-enterprise-server-docs.md |
Documentation |
LICENSE.txt |
License file (proprietary software) |
For deployment, install OpenJDK 17, unpack all files in a folder, and edit the properties file before running.
How to run the application
Start the Enterprise Server by running the java -jar flowcrypt-enterprise-server.jar
command.
The default command is to start the server at the localhost:32667
address. Other commands:
Command | Description |
---|---|
--version |
Print application version. |
--help |
Print application help. |
--test-store-connection |
Test the connection to your store, such as PostgreSQL, or your HSM/KMS. |
--gen-private-keys=<file.csv> |
Pre-generate private keys for your users. Supply a CSV file with one user per line of the following format: john.doe@corp.co,John Doe . The file must be in UTF-8 encoding if Non-ASCII characters are present. |
--create-db-encryption-key |
Create an encryption key for the database and either print it out or store it in KMIP. See the KMIP Configuration guide. |
Command line options:
Argument | Default | Description |
---|---|---|
--config=<cfg.properties> |
flowcrypt-enterprise-server.properties |
Config file path or an HTTP(S) URL |
Configuration
The sample properties file appropriate for your software version will come distributed along with the jar file. It consists of several sections:
- General Configuration and HTTPS
- High Availability and Scaling
- Keygen
- Encrypted Contact Page
- Web Portal
- Authentication
- ACL
- Orchestrator
- Store: Databases
- Store Encryption (EKM Only)
- Email Gateway
- File Storage
- Push Sync Using DatabaseStore
- Logging
- Feedback Form
Please read the Deployment Checklist and DNS guides before deploying the software.
Configuration: Common
General properties concerning the basic configuration and how you can access the app’s REST API:
Property | Description |
---|---|
web.security.key optional |
Used for encrypting/signing cookies and generating/verifying CSRF tokens. When left empty, a random key will be generated on each startup and users will be logged out when you restart the EAP. Example: random string |
web.cookies.secure optional |
Manually overwrite HTTPS secure cookie behavior. Example: true
|
services.eap.url |
The EAP service. This value is used for the cookie domain parameter and OIDC redirect_uri . The URL can be set to a custom path (e.g., https://localhost:32667/any/path/eap/ ).Example: https://localhost:32667/eap See the Authentication section on this page. |
services.ekm.url |
Your EKM instance, reachable by the EAP.html. Example: https://localhost:32667/ekm
|
services.fes.url |
Your FES, normally running on the fes subdomain.Example: https://localhost:32667/fes
|
services.wkd.url |
Your WKD, normally running on the openpgpkey subdomain.Example: https://localhost:32667/wkd
|
Configuration: Auth and ACL
Service authentication properties:
Property | Description |
---|---|
auth.service.orchestrator.enabled |
Set to true or false to enable/disable the use of the orchestrator service (normally from EAP to EKM). |
auth.service.orchestrator.verification.key |
Orchestrator verification key. If enabled, generate this using the --gen-jwk service-orchestrator command. |
auth.service.push-sync.signing.key |
See WKD Server. |
Other Configuration Options
Other properties you can find in the General section of the config file:
Property | Description |
---|---|
api.disable.domains |
A comma-separated list of disabled domains. The service will return ERROR 400 to requests from users on this domain, indicating they shouldn’t be using this service. The api.disable.domains=, property, including the comma, means an empty list. No domains are disabled, which is the default and expected value for most deployments. If a Client Configuration is explicitly set for this domain with a .ClientConfiguration.json file, the client configuration will be successfully returned even if the domain is on the api.disable.domains list. Conversely, if the domain is on the list and a domain-specific .ClientConfiguration.json file isn’t set, the API will return an error, even if the default client configuration from the default.ClientConfiguration.json file is available.Example: example1.com,example2.com
|
api.allow.end.user.to.delete.their.data optional |
Set to true or false to enable/disable the ability to delete end user data via the FES API.Default value: false Example: true
|
api.client.exception.notification.email.enabled |
Set to true or false to enable/disable the sending of a notification email when a new client exception is reported.Default value: false Example: true
|
api.client.exception.notification.email.address.from |
(for api.client.exception.notification.email.enabled ) Sets the email address from which to send a notification email when a new client exception is reported.Example: admin@company.com
|
api.client.exception.notification.email.addresses.to |
(for api.client.exception.notification.email.enabled ) A comma-separated list of email addresses. Sets the destination email address(es) to receive a notification email when a new client exception is reported.Example: dev@company.com (single email address) or dev@company.com,qa@company.com (multiple email addresses). |
Client Configuration
Our customers customize the behavior of the email client using the Client Configuration options by defining Domain Configurations.
Admin Panel Usage
Below are the most common usages of the general management that EAP offers:
- Add, rename, and delete end users
- Import and update private keys
- Import and update public keys
- View the list of keys
- Generate key pair
- Search for keys
- Bulk modification of private keys
- Key rotation
- Manage user IDs
- Manage associated users
- Manage key expiration
Sample config file
# https://flowcrypt.com/docs/technical/enterprise-server/latest/technical-overview.html
#####################################################
###################### GENERAL ######################
#####################################################
org.id=evaluation.org
api.hostname=0.0.0.0
api.port=32356
api.accept.hosts=localhost:32356
api.https.enabled=false
#api.https.key.file=flowcrypt-ekm-https-cert.p12
#api.https.key.password=password
api.cors.origins=*
api.error.format=id_only
api.accept.client.keypairs=true
api.openapi.enabled=false
api.disable.domains=,
api.allow.end.user.to.delete.their.data=false
api.client.exception.notification.email.enabled=false
api.client.exception.notification.email.address.from=
api.client.exception.notification.email.addresses.to=
# A symmetric key (random string) to use for encrypting/signing cookies and generating/verifying CSRF tokens.
# When left empty, a random key will be generated on each startup for use in the Admin Panel component, and Admin
# users will be logged out from the Enterprise Admin Panel when you restart the service.
# If you plan to run more than one service load-balanced, you must set the property below.
#web.security.key=
# Enterprise Server uses HTTPS-only cookies when running with 'api.https.enabled=true'. You can overwrite it below.
#web.cookies.secure=true
# TODO: In the future, ES will be just one service with internal calls. Therefore, the 4 lines below may not be needed.
#services.eap.url=https://localhost:32667/eap
#services.ekm.url=https://localhost:32667/ekm
#services.fes.url=https://localhost:32667/fes
#services.wkd.url=https://localhost:32667/wkd
# The truststore is optional and can be useful when you want to override the default JRE truststore in the following cases:
# - You are using WKD Push Sync, and WKD uses an HTTPS certificate signed by an internal CA.
# - You wish to verify a KMIP server.
# This truststore file then has to contain means to verify these certificates (e.g., a root CA cert).
#truststore.file=truststore-to-verify-kmip-server.p12
#truststore.password=password
#truststore.include.default=true
#####################################################
###################### Keygen #######################
#####################################################
# For "--gen-private-keys". The possible values are: curve25519 | rsa4096 | rsa3072 | rsa2048.
keygen.algo=curve25519
keygen.key.pair.expiration.days=365
keygen.rotation.set.superseded.key.pair.expiration.days=60
#####################################################
############# Encrypted Contact Page ################
#####################################################
api.contact.page.enabled=false
api.contact.page.message.email.address.from=
api.contact.page.notification.email.address.from=
api.contact.page.hcaptcha.enabled=false
api.contact.page.hcaptcha.site.key=
api.contact.page.hcaptcha.secret.key=
#####################################################
############ A Web Portal for decrypting ############
############ password-protected messages ############
#####################################################
#web.portal.url=https://fes.evaluation.org
web.portal.replies.sender.email=
web.portal.enforce.client.app.original.sender.email.address.match=true
web.portal.pubkey.source.attester.enabled=true
web.portal.wrong.password.attempts.before.timeout=5
web.portal.wrong.password.timeout.seconds=300
#####################################################
################# AUTHENTICATION ####################
#####################################################
# Do not change this end-user auth. It must correspond to the authentication used by the FlowCrypt client software.
auth.enduser.type=OidcAuthenticator
auth.enduser.idps=google
auth.enduser.google.issuer=https://accounts.google.com
auth.enduser.google.jwks=https://www.googleapis.com/oauth2/v3/certs
# Set from your admin OIDC settings.
auth.admin.type=OidcAuthenticator
auth.admin.idps=default
auth.admin.default.issuer=
#auth.admin.default.jwks=
auth.admin.default.audience=
#####################################################
####################### ACL #########################
#####################################################
acl.type=SimpleAcl
# The email addresses of administrator accounts, comma-separated.
acl.simple.admins=
#####################################################
################## Orchestrator #####################
#####################################################
# Set to true/false to enable/disable the use of the orchestrator service to handle automatic lifecycle actions on keys.
auth.service.orchestrator.enabled=
# If enabled, you should generate this using the EAP "--gen-jwk service-orchestrator" command.
# TODO: In the future, ES will be just one service with internal calls. Therefore, this will no longer be needed.
auth.service.orchestrator.verification.key=
#####################################################
#################### PUSH SYNC ######################
#####################################################
# TODO: In future ES versions, Push Sync will be internal, so the line below can be removed.
# For Push Sync
#wkd.url=https://localhost:32667/wkd
# TODO: In future ES versions, these calls will be internal, so this section can be removed.
# You can configure some instances to be read-only.
#wkd.push.readonly=false
# To limit IPs that can use the PUSH endpoints (IPs of EKM instances, comma-separated, empty means ALL IPs ALLOWED).
#wkd.push.source.ips=
# TODO: In the future, ES will be just one service with internal calls. Therefore, this will no longer be needed.
# For WKD Push Sync (optional). Generate a key pair using the "--gen-jwk=service-pushsync" command.
#auth.service.pushsync.signing.key=
# EKM authenticates itself with a self-issued JWT, which it verifies against the authentication public key.
#auth.service.pushsync.verification.key=
#####################################################
################# STORE: DATABASES ##################
#####################################################
##### PostgreSQL (recommended) #####
####################################
store.type=DatabaseStore
store.database.vendor=postgres
store.postgres.host=localhost
store.postgres.port=5432
store.postgres.database=db_enterprise_server
store.postgres.schema=public
store.postgres.update.schema=true
store.postgres.username=user_enterprise_server
store.postgres.connections=10
store.postgres.connection.timeout.seconds=5
store.postgres.connection.idletimeout.seconds=600
store.postgres.connection.maxlifetime.seconds=1740
#store.postgres.auth.method=password|cert
#store.postgres.auth.password=your_postgres_pwd
#store.postgres.auth.cert=/path/to/client.crt
#store.postgres.auth.key=/path/to/client.key
#store.postgres.auth.ca=/path/to/ca.crt
############ CockroachDB ############
#####################################
#store.type=DatabaseStore
#store.database.vendor=cockroach
#store.cockroach.host=localhost
#store.cockroach.port=26257
#store.cockroach.database=db_enterprise_server
#store.cockroach.schema=enterprise_server
#store.cockroach.update.schema=true
#store.cockroach.username=user_enterprise_server
#store.cockroach.connections=10
#store.cockroach.connection.timeout.seconds=5
#store.cockroach.connection.idletimeout.seconds=600
#store.cockroach.connection.maxlifetime.seconds=1740
#store.cockroach.auth.method=password|cert
#store.cockroach.auth.password=your_cockroachdb_pwd
#store.cockroach.auth.cert=/path/to/client.crt
#store.cockroach.auth.key=/path/to/client.key
#store.cockroach.auth.ca=/path/to/ca.crt
##### H2 database #####
###### (recommended for tests) ######
#####################################
#store.type=DatabaseStore
#store.database.vendor=h2
#store.h2.database.path=./data/enterprise_server_h2
#store.h2.connections=10
#store.h2.entire.database.encrypted=false
#store.h2.entire.database.encryption.password=
#store.h2.update.schema=true
#####################################################
################# STORE ENCRYPTION ##################
#####################################################
store.encryption.enable=true
# First, set the source below:
store.encryption.key.source=properties|stdin|kmip|pkcs11
# After, run "--create-db-encryption-key".
# Uncomment if store.encryption.key.source=properties.
# The DB encryption key set in the properties file directly.
#store.encryption.key.value=
# Uncomment if store.encryption.key.source=kmip.
# The DB encryption key retrieved over the KMIP protocol (e.g., Gemalto Safenet KeySecure or any compatible KMS).
# Remember to also set `truststore.file` above if the KMIP server uses certs with custom CA.
#store.kmip.hostname=localhost
#store.kmip.port=5696
#store.kmip.key.file=localhost.p12
#store.kmip.key.password=password
# The following identifier returned by "--create-db-encryption-key".
#store.kmip.encryption.key.identifier=
# This property is optional and is only used when creating a DB encryption key in KMIP.
# The default value is "flowcrypt-email-km-db-encryption-key".
#store.kmip.encryption.key.name=flowcrypt-email-km-db-encryption-key
# Uncomment if store.encryption.key.source=pkcs11.
# DB encryption key retrieved over PKCS#11 protocol (Fortanix SDKMS, Equinix SmartKey, or any compatible HSM).
#store.pkcs11.module=./vendor-pkcs11.so
#store.pkcs11.pin=file://vendor-pkcs11.cfg
#####################################################
################## EMAIL GATEWAY ####################
#####################################################
# This is useful for a quick demo, but should not be used for production.
email.gateway.type=LogOnly
# Comment out the line above, and uncomment this one, for production use.
# email.gateway.type=AmazonSes
email.gateway.amazonses.api.key=
email.gateway.amazonses.api.secret=
email.gateway.amazonses.region=eu-central-1
#####################################################
################## FILE STORAGE #####################
#####################################################
# Store uploaded password-protected messages in a file system.
# Can be used if the service isn't load-balanced, and you have an automatic backup mechanism in place for the file system.
file.storage.type=Filesystem
file.storage.fs.path=./fes-file-storage/
file.storage.fs.path.create=true
# Store uploaded password-protected messages on Amazon S3.
# This must be used if the service is load-balanced.
# file.storage.type=S3
# file.storage.s3.api.key=
# file.storage.s3.api.secret=
# file.storage.s3.region=eu-central-1
# file.storage.s3.bucket=flowcrypt-fes-storage
# file.storage.s3.expires.days=30
# file.storage.s3.download.url=https://bucket.s3.region.amazonaws.com
#####################################################
##################### LOGGING #######################
#####################################################
# A comma-separated list. The possible values are: StdoutLogger | FileLogger | StackdriverLogger | SplunkHttpLogger
logger.types=StdoutLogger
# The possible values are: trace | debug | info | warn | error
logger.default.level=info
#logger.stdout.include.datetime=true
#logger.file.folder=/var/logs
#logger.file.history.size=14
#logger.file.history.compression=false
#logger.file.include.datetime=true
#logger.stackdriver.credentials.file=/etc/google/auth/application_default_credentials.json
#logger.splunk.url=https://splunk-instance:8088
#logger.splunk.token=327bfa46-...
#logger.splunk.disable.certificate.validation=true
#####################################################
################## Feedback Form ####################
#####################################################
api.feedback.form.enabled=false
api.feedback.form.email.address.from=
api.feedback.form.email.address.to=