While JourneyApps goes to great lengths to secure all your apps automatically, the freedom and flexibility we aim to provide developers does in certain cases expose some pitfalls and limitations that developers should be aware of.
Out of the box, JourneyApps provides the following security mechanisms:
- All data is encrypted at rest and in transit using the strongest available encryption and transport protocols
- Client-side source code is obfuscated by default, and optionally encrypted
- All exposed API endpoints are encrypted using HTTPS
- Each customer organization is hosted in a highly secure, logically isolated sandbox
- Regular penetration testing of all cloud infrastructure and client runtimes are conducted
- Our annual SOC2 Type 2 Audit report is available to customers on request
Your app is therefore secure by default, however itâs worth taking the following into consideration for each app that you build.
1. Runtime / Container
App Code
All view JavaScript or TypeScript gets served to the client. On iOS itâs very hard for an app end-user to inspect this code. However using the web runtime, itâs easy to open the chrome developer tools and inspect the appâs source code. It is therefore recommended to avoid ever including and sensitive code such as API or encryption secrets in your app code - instead store these in CloudCode and use CloudCode.callTask, as end-users can never access the source code for a Cloudcode task.
App Data
As a reminder: there are three data ânamespacesâ available to developers:
- DB - data stored on the device and synced with the backend database
- LocalDB - data stored on the device but never synced anywhere
- OnlineDB - data stored in the backend database
The data in DB and LocalDB are encrypted by default (over and above the default OS-level file system encryption provided by modern operating systems). On iOS the DB encryption key is stored in the keychain. The data is similarly encrypted on Android and Windows. The only exception is the Web platform, where encryption of data is not feasible. Depending on your security model, the OS-level full disk encryption might be sufficient for data stored on disk by the web browser. If not, using OnlineDB
instead of DB
will avoid any data being synchronized to the client.
Furthermore, for web, itâs always possible for end users to open the developer console, and access the OnlineDB
object from the console. For this reason, itâs recommended to implement Data rules for apps being accessed using the Web container, especially when third parties such as customers or contractors will be accessing the app via web. Note that using OnlineDB from the browser developer console will not bypass the JourneyApps audit trail system, so all changes made by a user in this way will be audited.
2. Backend (Cloud) Database
All data stored in the JourneyApps backend are encrypted at rest, so there is nothing to be taken into account on that front. Having said that, the following are recommended best practice when using the JourneyApps backend:
- When creating Backend Users, always remember to apply the principle of least privilege, and assign the user the most restrictive role available (i.e. Data Manager vs Admin)
- Remember to use the
text:password
field data type for any sensitive fields stored in the DB - If using the Backend API, itâs recommended to use single-purpose named tokens, and to disable the username and password authentication. Administrators can create two named tokens for each use case for key rotation.
Securing Webhooks (Advanced)
When using external webhooks, all outbound (POST) requests will be encrypted using TLS. If you want to authenticate webhook requests, you can use the X-Journey-Signature
field in the request header. This field is calculated using HMAC-SHA256, where the data
is the raw request body, and the key
is the âSecretâ field on the âLogsâ page for your webhook in the JourneyApps Backend Databrowser. Using OpenSSL, this would be calculated as OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new(âsha256â), key, data)
Alternatively, you can also use certificate-based authentication. The X-Journey-Signature-RSA-SHA256-Key-ID
header is the CN of the certificate, and the certificate itself can be obtained from your customer success representative upon request.
3. CloudCode
Since CloudCode tasks are ephemeral (i.e. they spin up, execute, and shut down), there is no attack surface. For most tasks, standard security practices apply (avoid making plaintext http API calls, donât overwrite the default fetch SSL configuration, etc.). The exception is for Web Tasks, where special precautions are required:
- Make sure you implement authentication using a strong key - donât simply
return access.authorized
- If you include any npm packages into your webtask, make sure you monitor security announcements for these packages, and upgrade them when required
- If you accept and use any dynamic parameters to your task, make sure to sanitize these parameters, especially if combining with the nodeJS
fs
module, since unsanitized parameters could enable directory traversal attacks.
4. User Authentication
- Enrolled devices will remain enrolled indefinitely. If periodic re-enrollment is required (e.g. every 30 days), your customer success representative can provide you with advice and code snippets for how to achieve this.
- Signed SAML requests and responses are supported for customers on our Enterprise plan.
- Best-practices for authentication on shared devices are available from your customer success representative.