MYOWNMDM / DOCUMENTATION

Installation

Deploy from an obtained source checkout. Provision the trust boundary before enrolling endpoints.

Before you start.

No public software release or verified public container registry is available yet. Contact EnigmaIS for early access and agree the relevant evaluation or commercial terms. Run application commands below from the obtained application checkout, not from this static website folder.

The current package names are devica and devica-serve. Choose a dedicated device DNS suffix, a stable HTTPS address reachable by your endpoints, and a CA signing process for the constrained device sub-CA.

Docker Compose.

Install Docker Engine with Compose v2. The application image is built locally from the obtained source; its cryptographic core is vendored, so another application checkout is not needed.

Build the image and prepare lab HTTPS material if needed
./scripts/build-image.sh
# Lab only: create a self-signed HTTPS certificate.
./scripts/gen-lab-cert.sh

For production, provide a suitable HTTPS certificate and key as tls/tls.crt and tls/tls.key. The lab helper creates a self-signed localhost certificate; remote endpoints require a suitable service certificate and established HTTPS trust.

Update the application Compose configuration with your actual namespace and URL:

Example Compose environment values
# ca.environment in docker-compose.yml
DEVICA_DEVICE_DNS_SUFFIX: "devices.example.com"
DEVICA_ENROLLMENT_BASE_URL: "https://enrollment.example.com"
DEVICA_COOKIE_SECURE: "true"

If no keystore passphrase is supplied, the container entrypoint generates one in the state volume’s secrets.env. Preserve it for the lifetime of the stored keys; changing the passphrase does not re-encrypt existing keys.

Start the stack and read its first-run setup token
docker compose up -d
docker compose logs ca

Find the setup token in the ca logs. Open your HTTPS service’s /setup page and create the first administrator. The proxy forwards to the internal app on port 8800; the devica-state volume holds the database, keys, and secret file.

Provision the device sub-CA.

Choose one provisioning path on a fresh instance. For a lab, initialise a self-issued, constrained RSA authority:

Lab-only sub-CA provisioning
# A fresh evaluation instance only.
docker compose exec ca devica subca init-lab \
  --cn "DeviceCA Lab Sub-CA" --algorithm rsa-3072
docker compose exec ca devica subca status

For production, generate a request and transfer it to myOwnCA or a suitable signing authority:

Generate and export the production sub-CA request
docker compose exec ca devica subca gen-csr \
  --cn "DeviceCA Sub-CA" --algorithm rsa-3072 \
  --out /var/lib/devica/subca.csr
docker compose cp ca:/var/lib/devica/subca.csr ./subca.csr

Have your CA sign it as a subordinate CA with the requested device DNS name constraints. The returned certificate must match the pending key and permit your configured suffix. The first certificate in chain.pem must directly sign the sub-CA.

Import the signed sub-CA and issuer chain
# After your CA returns subca.crt and the issuer-first chain.pem:
docker compose cp ./subca.crt ca:/var/lib/devica/subca.crt
docker compose cp ./chain.pem ca:/var/lib/devica/chain.pem
docker compose exec ca devica subca import-cert \
  --cert /var/lib/devica/subca.crt --chain /var/lib/devica/chain.pem
docker compose exec ca devica subca status

Use RSA for this authority. Do not replace an existing active sub-CA by rerunning lab setup; arrange CA rollover separately. A pending request blocks a second request unless explicitly abandoned with --force.

Local Python 3.12 or newer.

Install from the obtained source into a virtual environment. The following example generates a persistent keystore passphrase on a fresh installation. It loads automatically from the state directory for both the web service and CLI.

Install and start the Python application
python3 -m venv .venv
.venv/bin/pip install .
export DEVICA_STATE_DIR="$PWD/var"
export DEVICA_DEVICE_DNS_SUFFIX="devices.example.com"
export DEVICA_ENROLLMENT_BASE_URL="https://enrollment.example.com"
export DEVICA_COOKIE_SECURE=true
umask 077
mkdir -p "$DEVICA_STATE_DIR"
# Once on a fresh installation: generate and persist the keystore secret.
if [ ! -f "$DEVICA_STATE_DIR/secrets.env" ]; then
  .venv/bin/python -c 'import secrets; print("DEVICA_KEYSTORE_PASSPHRASE=" + secrets.token_urlsafe(32))' \
    > "$DEVICA_STATE_DIR/secrets.env"
fi
.venv/bin/devica-serve

devica-serve binds to 0.0.0.0:8800. Place it behind an HTTPS reverse proxy and limit direct network access to the backend. Keep secure cookies enabled for the HTTPS portal. Use a protected state directory owned by the service account.

Read the first-run setup token in server output, complete /setup, and provision the authority in another terminal using the same state and namespace:

Provision the production authority with the local CLI
# In a second terminal, use the same state directory and settings.
export DEVICA_STATE_DIR="$PWD/var"
export DEVICA_DEVICE_DNS_SUFFIX="devices.example.com"
export DEVICA_ENROLLMENT_BASE_URL="https://enrollment.example.com"
export DEVICA_COOKIE_SECURE=true
.venv/bin/devica subca gen-csr --cn "DeviceCA Sub-CA" \
  --algorithm rsa-3072 --out "$DEVICA_STATE_DIR/subca.csr"
# Have your CA sign the CSR, then import the returned files:
.venv/bin/devica subca import-cert --cert subca.crt --chain chain.pem
.venv/bin/devica subca status

For a fresh local lab, replace the CSR/import steps with .venv/bin/devica subca init-lab --cn "DeviceCA Lab Sub-CA" --algorithm rsa-3072. Use a service manager to preserve the deployment settings and restart the web process.

Optional MariaDB.

SQLite is the default. The Docker image includes the MariaDB driver; the bundled overlay adds a database service and points the app at it. Set your deployment’s database password before starting:

Start the bundled MariaDB overlay
# Set DEVICA_DB_PASSWORD in your protected deployment environment.
docker compose -f docker-compose.yml -f docker-compose.mariadb.yml up -d

For a separately managed database, set DEVICA_DATABASE_URL to your mysql+pymysql:// connection URL and install the local package with .venv/bin/pip install '.[mariadb]'. Protect database credentials. Schema migrations run at application startup.

Changing the backend does not migrate an existing SQLite inventory. Use an agreed migration procedure for existing state, and back up both the database and encrypted keys. Continue with device enrolment and backup planning.

Planning a deployment?

Talk to EnigmaIS