Security

This document serves as a place to outline our security practices and details. If a potential customer (or auditor) needs information about our security at Holder, this should be the first place we pull information from. It should be kept up to date as much as possible every time we modify or improve our security.

Services

UI

Our UI/application is secured with Google's Firebase Auth using JWT verification (see more below). We have a few public endpoints for form collection of customer information, but that is secured using Rainbow Kit to connect a wallet (and will soon utilize Sign-In With Ethereum with the Firebase JWTs).

API

Our API is secured with Google's Firebase Auth using JWT verification (see more below). We have a few public query endpoints for display only information about a given Holder account (no customer information).

Data Collection

Our Data Collection API is an internal only API that is secured via an x-api-key header stored as a secure variable during our deployment process with Cloud Run.

Transfers

Our Transfers API is deployed behind a VPC connector and is limited to internal traffic only. It is primarily meant to pull messages off of a PubSub topic to be processed. It has a few REST endpoints that are protected by an x-api-key header.

Workflow Automation

Our Workflow Automation API is deployed behind a VPC connector and is limited to internal traffic only. It is primarily meant to process messages being pushed to it from a PubSub topic. It is using the Google Cloud Functions Framework package to handle the networking configuration.

Discord

Our Discord bot is deployed without any external endpoints at this time, but it cannot be deployed behind the VPC to limit to internal only traffic. It is only using the discord.js SDK to listen for events from Discord given our Discord application's CLIENT_ID. We gather data from Discord guilds and validate Discord users. We only do that through an OAuth flow with Discord.

Infrastructure

Cloud Run

Our services are all deployed using Google's Cloud Run deployment. It puts every endpoint behind a load balancer that secures them via https/TLS, which encrypts traffic in transit.

Neo4j AuraDB

This is a managed service provided by Neo4j. We are currently on their Professional plan, which is outlined here. You can also see the additional features included in their Enterprise plan if we needed to upgrade. Here are some of the high level points it provides:

  • Encryption at rest and in transit

  • Daily backups (with 7 day retention)

More details can be found here.

Redis Memorystore

This is a managed service in GCP. It is deployed behind a VPC connector and is limited to internal traffic only.

More details can be found here and here.

Firebase Authentication

We are using Google's Firebase Auth as our Identity Provider. More information can be found here.

Deploying Services

We are using Google Cloud Run to deploy our services from Docker containers

GitHub

Our GitHub repositories are private and not currently available to the public.

Cloud Storage

We have a Google Cloud Storage bucket that is marked as "public" for uploading images for our Email Builder.

Secret Manager

We store all of our API keys, passwords, and secrets in a Secret Manager secret that gets injected into every Cloud Run service we deploy.

Integrations

Intercom

This is an integration from Intercom that gives Holder the ability to chat with users, give product tours, display temporary banners, and event tracking. User Identity Verification is being used and is provided by Intercom. Get more info about Intercom security here.

XMTP

This is a secure messaging protocol integrated with blockchain technology that we allow our customers to send marketing messages through. They had a security assessment done by Certik, and more information on that can be found here.

Due to the nature of our application and how we interact with the XMTP network we must store a users XMTP specific key bundle server side. For this we are using one of the most trusted encryption standards to store an encoded buffer of these keys while following best practices outlined by XMTP.

Last updated