The SSI Service supports multiple storage technologies. All storage operations are abstracted away by an interface. The interface is based was designed as a Key Value store that supports optimistic concurrency. We provide implementations out of the box for Redis, SQL, and Bolt.
You can configure SSI service to use Redis by setting the following options in your TOML configuration.
[services]
storage = "redis"
[[services.storage_option]]
id = "redis-address-option"
option = "redis:6379"
[[services.storage_option]]
id = "storage-password-option"
option = "password"
For a working example, see this prod.toml file
Depending on your data needs, you may want to choose different Redis persistence strategies. For the most durable and disaster recovery ready alternative, please make sure to turn on RBD + AOF, with AOF doing an fsync for every write. More details are available in the Redis Persistence page.
You can configure SSI service to use any database/sql
driver by setting the following options in your TOML configuration.
[services]
storage = "database_sql"
[[services.storage_option]]
id = "sql-connection-string-option"
option = "host=localhost port=5432 user=postgres password=postgres dbname=postgres sslmode=disable"
[[services.storage_option]]
id = "sql-driver-name-option"
option = "postgres"
SSI-service's SQL implementation includes the github.com/lib/pq
driver for PostgreSQL. If you need to support for an
additional driver, please open a PR.
You can configure it by setting the following options in your TOML configuration.
[services]
storage = "bolt"
[[services.storage_option]]
id = "boltdb-filepath-option"
option = "bolt.db"
For a working example, see this dev.toml file
You need to implement the ServiceStorage interface, similar to how Redis is implemented. For an example, see this PR which introduces the SQL based implementation.
SSI Service supports application level encryption of values before sending them to the configured KV store. Please note that keys (i.e. the key of the KV store) are not currently encrypted. See the Privacy Considerations for more information. A MasterKey is used (a.k.a. a Data Encryption Key or DEK) to encrypt all data before it's sent to the configured storage. The MasterKey can be stored in the configured storage system or in an external Key Management System (KMS) like GCP KMS or AWS KMS. When storing locally, the key will be automatically generated if it doesn't exist already.
For production deployments, it is strongly recommended to store the MasterKey in an external KMS.
To use an external KMS:
- Create a symmetric encryption key in your KMS. You MUST select the algorithm that uses AES-256 block cipher in Galois/Counter Mode (GCM). At the time of writing, this is the only algorithm supported by AWS and GCP.
- Set the
master_key_uri
field of the[services.storage_encryption]
section using the format described in tink (we use the tink library under the hood). - Set the
kms_credentials_path
field of the[services.storage_encryption]
section to point to your credentials file, according to this section. - Win!
Below, there is an example snippet of what the TOML configuration should look like.
[services.storage_encryption]
# Make sure the following values are valid.
master_key_uri = "gcp-kms://projects/*/locations/*/keyRings/*/cryptoKeys/*"
kms_credentials_path = "credentials.json"
disable_encryption = false
Storing the MasterKey in the configured storage system is done with the following options in your TOML configuration.
[services.storage_encryption]
# ensure that master_key_uri is NOT set.
disable_encryption = false
Disabling app level encryption is also possible using the following options in your TOML configuration:
[services.storage_encryption]
# encryption
disable_encryption = true
From the perspective of SSI-Service, all keys are stored in plaintext (this doesn't preclude configuring encryption at rest in your deployment of the storage configuration). Making all keys readable by any actor may have an impact in your organization's use cases around privacy. You should consider whether this is acceptable. Notably, a DID that was created by SSI Service is stored as a key. This can fit some definition of PII, as it could be correlated to identify and individual.
Encrypting keys is being considered in #603.