version: 2024-02
Prerequisites |
---|
You’re familiar with all the Enterprise Server services. |
Enterprise customers may deploy FlowCrypt External Service (FES) on their own premises to centrally manage the Client Configuration distribution, log collection, and the Web Portal for password-protected messages.
The FES REST JSON API is accessed by FlowCrypt email encryption client apps, either internally within your network or over the public internet. FES should therefore be deployed in the DMZ.
Requirements
All requirements described in Enterprise Server Deployment Requirements, plus the following:
Type | Requirement |
---|---|
Database | Required for storing password-protected message metadata. PostgreSQL or CockroachDB for production. H2 for testing & evaluation. |
Network | FES must be accessible publicly at the https://fes.yourdomain.com address. Limited external access to the internet to fetch Google JWK for user authentication, send emails using Amazon SES, and interact with Amazon S3. |
Distribution and deployment
FlowCrypt External Service is distributed as a zip file containing:
Filename | Description |
---|---|
flowcrypt-external-service.jar |
Runnable Java JAR |
flowcrypt-external-service.properties |
Default config for FES |
flowcrypt-external-service-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 FES by running the java -jar flowcrypt-external-service.jar
command.
The default command is to start the server at the localhost:32337
address. Other commands:
Command | Description |
---|---|
--version |
Print application version |
--help |
Print application help |
--gen-jwk |
Generate JWK for service authentication |
Command line options:
Argument | Default | Description |
---|---|---|
--config=<cfg.properties> |
flowcrypt-external-service.properties |
Config file path or an HTTP(S) URL |
Configuration
The sample configuration 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
- Encrypted Contact Page
- Web Portal
- Authentication
- ACL
- Store: Databases
- Email Gateway
- File Storage
- Logging
- Feedback Form
Please read the Deployment Checklist guide before deploying the software.
Configuration: Auth and ACL
Service authentication properties specific to FES:
Property | Description |
---|---|
auth.service.orchestrator.enabled |
Set to true or false to enable/disable the use of the orchestrator service from EAP to FES. |
auth.service.orchestrator.verification.key |
FES orchestrator verification key. If enabled, generate this using the EAP --gen-jwk service-orchestrator command. |
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.
Sample config file
# https://flowcrypt.com/docs/technical/external-service/latest/technical-overview.html
#####################################################
################## GENERAL - FES ####################
#####################################################
org.id=evaluation.org
api.hostname=0.0.0.0
# Users need to be able to access this server over the HTTPS 443 port:
# - When using a Reverse Proxy for SSL termination, you can leave the port below as is (or choose any port you like)
# and have the Reverse Proxy serve users at the 443 port.
# - When not using a Reverse Proxy, you need to set the 443 port below and enable HTTPS below.
api.port=32337
api.accept.hosts=localhost:32337
api.https.enabled=false
#api.https.key.file=flowcrypt-external-service.p12
#api.https.key.password=password
api.error.format=id_only
api.cors.origins=*
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=
# The Optional Truststore to override the default JRE Truststore, and to verify internal SSL certs.
#truststore.file=truststore.p12
#truststore.password=password
#truststore.include.default=true
#####################################################
############# 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
# Copy this configuration from the EAP "auth.admin" section.
auth.admin.type=OidcAuthenticator
auth.admin.idps=default
auth.admin.default.issuer=
auth.admin.default.jwks=
# You should get this client ID value from your IdP app.
auth.admin.default.audience=
# Set to true/false to enable/disable the use of the Orchestrator service from EAP to FES.
auth.service.orchestrator.enabled=
# If enabled, you should generate this using the EAP "--gen-jwk service-orchestrator" command.
auth.service.orchestrator.verification.key=
#####################################################
####################### ACL #########################
#####################################################
acl.type=SimpleAcl
# The email addresses of administrator accounts, comma-separated.
acl.simple.admins=
#####################################################
################# STORE: DATABASES ##################
#####################################################
##### PostgreSQL (recommended) #####
####################################
store.type=DatabaseStore
store.database.vendor=postgres
store.postgres.host=localhost
store.postgres.port=5432
store.postgres.database=db_fes
store.postgres.schema=public
store.postgres.update.schema=true
store.postgres.username=user_fes
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_fes
#store.cockroach.schema=fes
#store.cockroach.update.schema=true
#store.cockroach.username=user_fes
#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=cert
#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/fes_h2
#store.h2.connections=10
#store.h2.entire.database.encrypted=false
#store.h2.entire.database.encryption.password=
#store.h2.update.schema=true
#####################################################
################## EMAIL GATEWAY ####################
#####################################################
email.gateway.type=LogOnly
#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 on 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.
# 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=