Use Kubernetes Data Storage

On this page

Data Storage Overview

This guide provides a brief summary of ways to manage data when the Curity Identity Server runs in Kubernetes. The content includes some example commands for developers new to Kubernetes data storage. If you use the Curity Token Handler there is no backend data storage to manage, since HTTP cookies contain all state.

The Curity Identity Server uses configuration data for most security settings, to support parameterized deployments. For other data, like user accounts, user credentials, session data and token-related information, it depends on one or more data sources.

Use a Durable Data Source

By default, the Curity Identity Server uses a simple in-memory database, which provides convenient options to enable developers to get started quickly. Workloads lose all identity data when they restart, so in-memory storage is only suitable for demo environments. For other environments, update to a durable data source.

The product documentation on Data Sources provides details on the supported data protocols, like JDBC, LDAP or SCIM. Most commonly, you configure the Curity Identity Server to use JDBC to connect to a SQL database. You should be able to use the same type of data storage for the Curity Identity Server that you already use for APIs, like PostgreSQL or Microsoft SQL Server. Start with the Get Connected to SQL Data Sources tutorial.

The Curity Identity Server uses connection strings to data sources. By default, you only need a single data source and express the connection as configuration parameters, whose values differ for each stage of your deployment pipeline. You can use multiple data sources in more advanced deployments, such as those for multiple regions and tenants.

xml
1234567891011
<data-sources>
<data-source>
<id>default-datasource</id>
<jdbc xmlns="https://curity.se/ns/ext-conf/jdbc">
<connection-string>#{DB_CONNECTION}</connection-string>
<driver>#{DB_DRIVER}</driver>
<password>#{DB_PASSWORD}</password>
<username>#{DB_USER}</username>
</jdbc>
</data-source>
</data-sources>

Select the Type of Storage

A basic durable solution might provision external disk storage from a cloud provider, with RAID-like guarantees and snapshotting capabilities to enable data backup and restore. Once the disk is ready, your database pod can use that storage to persist its data.

As part of your base Kubernetes setup, you may need to install a particular Container Storage Interface (CSI) driver, that provides Storage Classes that you use to request types of persistent volumes for data storage. For example, on the Amazon platform, you might need to deploy the Amazon Elastic Block Store (EBS) CSI driver to enable the use of gp3 volumes.

Kubernetes enables many data source deployment patterns. You can combine the capabilities of the database software, the hosting platform and the storage options that Kubernetes provides.

Use Persistent Volumes

To avoid data loss if a pod or node gets replaced or even if you redeploy the entire cluster, use Persistent Volumes. One option is dynamic provisioning where you declare a PersistentVolumeClaim that references a storage class name and size. The CSI driver for the storage class then automatically creates the PersistentVolume object and binds it to the claim, to mount an external volume into the data source pod.

yaml
12345678910111213
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: idsvr-claim
labels:
app: postgres
spec:
storageClassName: ebs-sc
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

Deploy the Database Schema

The Helm chart for the Curity Identity Server enables you to run a Docker job container that uses the Liquibase tool to keep the database schema up to date. The Upgrade Data Sources tutorial explains more about the mechanism. You could save the following content to a helm values.yml file and use it in an example deployment.

yaml
12345678910111213141516171819202122232425
replicaCount: 2
image:
repository: curity.azurecr.io/curity/idsvr
tag: latest
curity:
adminUiHttp: true
admin:
logging:
level: INFO
runtime:
logging:
level: INFO
config:
uiEnabled: true
dbSchemaManagementJob:
enabled: true
environmentVariableSecrets:
- idsvr-dbinit-parameters
serviceAccount:
name: idsvr-dbinit

Enabling the dbSchemaManagementJob causes a job container to run, which initializes or upgrades the schema if required, and then exits. The job container needs database connection details with sufficient permissions to change the schema. The following example shows how to encode the required environment variables into a Kubernetes secret.

bash
1234
kubectl -n curity create secret generic idsvr-dbinit-parameters \
--from-literal="JDBC_USERNAME=idsvruser" \
--from-literal="JDBC_PASSWORD=Password1" \
--from-literal="JDBC_URL=jdbc:postgresql-svc://dbserver:5432/idsvr"

Get Started with Local Persistent Volumes

If you are new to Kubernetes data storage, you can rehearse durable deployments on a local computer. To simulate external storage in KIND you can create a cluster and share a folder, that acts as the root storage location, from the host computer to Kubernetes nodes.

bash
123456789101112
cat << EOF > cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: oauth
nodes:
- role: control-plane
- role: worker
extraMounts:
- hostPath: ./externalstorage
containerPath: /var/local-path-provisioner/host
EOF
kind create cluster --config=cluster.yaml

A KIND cluster uses the local-path-provisioner storage class and assigns it a name of standard. For example, the Helm chart for the Curity product includes an option to use a PersistentVolume to store the configuration database. To implement that use case, use static provisioning to create a PersistentVolume. Use storageClassName=standard and specify a subfolder like idsvr-configuration within the root storage location.

bash
1234567891011121314151617
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-configuration
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 1Gi
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
volumeMode: Filesystem
hostPath:
path: /var/local-path-provisioner/host/idsvr-configuration
type: DirectoryOrCreate
EOF

The following values.yaml file represents a deployment for the Curity Identity Server that stores the configuration database in a PersistentVolume. Behind the scenes, the Helm chart creates a PersistentVolumeClaim that requests read and write access to a PersistentVolume of the standard storageClass. If Kubernetes identifies a PersistentVolume that matches the claim and that is available, like the PersistentVolume from above, it grants the claim and the Curity Identity Server can persist its data using the PersistentVolume.

yaml
1234567891011121314151617181920212223
replicaCount: 2
image:
repository: curity.azurecr.io/curity/idsvr
tag: latest
curity:
adminUiHttp: true
admin:
logging:
level: INFO
runtime:
logging:
level: INFO
config:
uiEnabled: true
persistentConfigVolume:
enabled: true
storageClass: standard
accessModes: ReadWriteOnce
size: 1Gi

Run the Helm chart with the following options, to reference the Helm values.yaml file and its durable storage settings:

bash
123456
helm repo add curity https://curityio.github.io/idsvr-helm/
helm repo update
helm install curity curity/idsvr --values=values.yaml \
--namespace curity \
--create-namespace \
--set curity.config.password=Password1

Next, query deployed persistent volumes and persistent volume claims:

bash
1
kubectl get pv,pvc -A

You should see the PersistentVolume and PersistentVolumeClaim bound together:

text
12345
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS
persistentvolume/pv-configuration 1Gi RWO Retain Bound curity/curity-idsvr standard
NAMESPACE NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS
curity persistentvolumeclaim/curity-idsvr Bound pv-configuration 1Gi RWO standard

You can then view the configuration database files in the idsvr-configuration folder of the root ./externalstorage location on your local computer. If you delete a pod, or even recreate the whole local cluster, the next deployment continues to use the existing configuration database. Once you understand the durable data approach, you can use it for other data sources, like SQL databases.

Example Database Deployment

The GitHub link at the top of this page provides some Kubernetes example deployments for a local computer. The Curity Identity Server example includes a basic deployment of a PostgreSQL database with a storage class and persistent volume that store files on the local filesystem. The example deployment also shows how to activate the DevOps Dashboard to administer user accounts and other identity data. Finally, the tutorial shows how to connect to the database and query its data, to get to know the schema.

Summary

The Curity Identity Server can run in Kubernetes and connect to many types of new or existing data sources using standard protocols. Deploy data sources so that data saves to PersistentVolumes. You can provide either basic durability or a more advanced deployment for multiple regions or availability zones.

Architecture

See how Curity fits into modern identity and API architectures.

Explore architecture

Customer Stories

Learn how organizations run identity and API security at scale.

Read customer stories