Files
magistrala/domains/README.md
T
Dušan Borovčanin 61d0427898 NOISSUE - Rename to Magistrala (#3427)
Signed-off-by: dusan <borovcanindusan1@gmail.com>
2026-04-06 15:23:42 +02:00

21 KiB
Raw Blame History

Domains

The Domains service provides an HTTP API for managing platform domains in Magistrala. Through this API you can create, list, retrieve, update, enable/disable/freeze domains, manage roles & invitations associated with domains, and more.

For more background on Magistrala concepts, see the official documentation.

Configuration

The service is configured through environment variables (unset variables fall back to defaults).

Variable Description Default
MG_DOMAINS_LOG_LEVEL Log level for Domains (debug, info, warn, error) debug
MG_DOMAINS_HTTP_HOST Domains service HTTP host domains
MG_DOMAINS_HTTP_PORT Domains service HTTP port 9003
MG_DOMAINS_HTTP_SERVER_CERT Path to PEM-encoded HTTP server certificate ""
MG_DOMAINS_HTTP_SERVER_KEY Path to PEM-encoded HTTP server key ""
MG_DOMAINS_GRPC_PORT Domains service gRPC port 7003
MG_DOMAINS_GRPC_SERVER_CERT Path to PEM-encoded gRPC server certificate ""
MG_DOMAINS_GRPC_SERVER_KEY Path to PEM-encoded gRPC server key ""
MG_DOMAINS_GRPC_SERVER_CA_CERTS Path to trusted CA bundle for the gRPC server ""
MG_DOMAINS_GRPC_CLIENT_CA_CERTS Path to client CA bundle to require gRPC mTLS ""
MG_DOMAINS_DB_HOST Database host address domains-db
MG_DOMAINS_DB_PORT Database host port 5432
MG_DOMAINS_DB_USER Database user magistrala
MG_DOMAINS_DB_PASS Database password magistrala
MG_DOMAINS_DB_NAME Name of the database used by the service domains
MG_DOMAINS_DB_SSL_MODE Database connection SSL mode (disable, require, verify-ca, verify-full) ""
MG_DOMAINS_DB_SSL_CERT Path to the PEM-encoded certificate file ""
MG_DOMAINS_DB_SSL_KEY Path to the PEM-encoded key file ""
MG_DOMAINS_DB_SSL_ROOT_CERT Path to the PEM-encoded root certificate file ""
MG_DOMAINS_CACHE_URL Cache database URL redis://domains-redis:6379/0
MG_DOMAINS_CACHE_KEY_DURATION Cache key duration for domain status/route lookups 10m
MG_DOMAINS_INSTANCE_ID Domains instance ID (auto-generated when empty) ""
MG_SPICEDB_HOST SpiceDB host for policy checks magistrala-spicedb
MG_SPICEDB_PORT SpiceDB port 50051
MG_SPICEDB_SCHEMA_FILE Path to SpiceDB schema file used to seed available actions ./docker/spicedb/schema.schema.zed
MG_SPICEDB_PRE_SHARED_KEY SpiceDB preshared key 12345678
MG_ES_URL Event store URL nats://localhost:4222
MG_JAEGER_URL Jaeger server URL http://localhost:4318/v1/traces
MG_JAEGER_TRACE_RATIO Trace sampling ratio 1.0
MG_SEND_TELEMETRY Send telemetry to the Magistrala call-home server true
MG_AUTH_GRPC_URL Auth service gRPC URL ""
MG_AUTH_GRPC_TIMEOUT Auth service gRPC request timeout 1s
MG_AUTH_GRPC_CLIENT_CERT Path to the PEM-encoded Auth gRPC client certificate ""
MG_AUTH_GRPC_CLIENT_KEY Path to the PEM-encoded Auth gRPC client key ""
MG_AUTH_GRPC_SERVER_CA_CERTS Path to the PEM-encoded Auth gRPC trusted CA bundle ""
MG_DOMAINS_CALLOUT_URLS Comma-separated list of HTTP callout targets invoked on domain operations ""
MG_DOMAINS_CALLOUT_METHOD HTTP method for callouts (POST or GET) POST
MG_DOMAINS_CALLOUT_TLS_VERIFICATION Verify TLS certificates for callouts true
MG_DOMAINS_CALLOUT_TIMEOUT Callout request timeout 10s
MG_DOMAINS_CALLOUT_KEY Client key for mTLS callouts ""
MG_DOMAINS_CALLOUT_OPERATIONS Comma-separated list of operation names that should trigger callouts ""

Note: Set MG_DOMAINS_CALLOUT_OPERATIONS to a subset of OpCreateDomain, OpRetrieveDomain, OpUpdateDomain, OpEnableDomain, OpDisableDomain, OpFreezeDomain, OpListDomains, OpViewDomainInvitation, OpSendInvitation, OpAcceptInvitation, OpListInvitations, OpListDomainInvitations, OpRejectInvitation, or OpDeleteInvitation to filter which actions produce callouts.

Deployment

The service is distributed as a Docker container. See the domains section of the compose file for an example deployment.

To run the service outside of a container:

# download the latest version of the service
git clone https://github.com/absmach/magistrala
cd magistrala

# compile the domains service
make domains

# copy binary to $GOBIN
make install

# set the environment variables and run the service
MG_DOMAINS_LOG_LEVEL=debug \
MG_DOMAINS_CACHE_URL=redis://domains-redis:6379/0 \
MG_DOMAINS_CACHE_KEY_DURATION=10m \
MG_DOMAINS_HTTP_HOST=domains \
MG_DOMAINS_HTTP_PORT=9003 \
MG_DOMAINS_HTTP_SERVER_CERT="" \
MG_DOMAINS_HTTP_SERVER_KEY="" \
MG_DOMAINS_GRPC_HOST=domains \
MG_DOMAINS_GRPC_PORT=7003 \
MG_DOMAINS_GRPC_SERVER_CERT="" \
MG_DOMAINS_GRPC_SERVER_KEY="" \
MG_DOMAINS_GRPC_SERVER_CA_CERTS="" \
MG_DOMAINS_GRPC_CLIENT_CA_CERTS="" \
MG_DOMAINS_DB_HOST=domains-db \
MG_DOMAINS_DB_PORT=5432 \
MG_DOMAINS_DB_USER=magistrala \MG_DOMAINS_DB_PASS=magistrala \MG_DOMAINS_DB_NAME=domains \
MG_DOMAINS_DB_SSL_MODE="" \
MG_DOMAINS_DB_SSL_CERT="" \
MG_DOMAINS_DB_SSL_KEY="" \
MG_DOMAINS_DB_SSL_ROOT_CERT="" \
MG_AUTH_GRPC_URL="" \
MG_AUTH_GRPC_TIMEOUT=1s \
MG_AUTH_GRPC_CLIENT_CERT="" \
MG_AUTH_GRPC_CLIENT_KEY="" \
MG_AUTH_GRPC_SERVER_CA_CERTS="" \
MG_SPICEDB_HOST=localhost \
MG_SPICEDB_PORT=50051 \
MG_SPICEDB_SCHEMA_FILE=./docker/spicedb/schema.schema.zed \
MG_SPICEDB_PRE_SHARED_KEY=12345678 \
MG_ES_URL=nats://localhost:4222 \
MG_JAEGER_URL=<http://localhost:4318/v1/traces> \
MG_JAEGER_TRACE_RATIO=1.0 \
MG_DOMAINS_CALLOUT_URLS="" \
MG_DOMAINS_CALLOUT_METHOD=POST \
MG_DOMAINS_CALLOUT_TLS_VERIFICATION=true \
MG_DOMAINS_CALLOUT_TIMEOUT=10s \
MG_DOMAINS_CALLOUT_KEY="" \
MG_DOMAINS_CALLOUT_OPERATIONS="" \
MG_SEND_TELEMETRY=true \
MG_DOMAINS_INSTANCE_ID="" \
$GOBIN/magistrala-domains

Usage

Domains supports the following operations:

Operation Description
create Create a new domain with a unique route
get Retrieve a domain (optionally with role memberships) or list accessible domains
update Update a domains name, tags, or metadata
enable Enable a previously disabled domain
disable Disable an active domain
freeze Freeze a domain (platform administrators only)
invite Send an invitation for a user to join a domain with a specific role
invitations List invitations for the current user or for a specific domain
accept/reject Accept or reject a pending domain invitation
delete-invitation Delete an invitation (inviter, invitee, or admin)
roles Create/list/update/delete domain roles; manage role actions and members; list actions

API Examples

Create a Domain

curl -X POST http://localhost:9004/domains \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Edge Tenant",
    "route": "edge",
    "tags": ["iot", "prod"],
    "metadata": { "region": "eu-west-1" }
  }'

Expected response:

{
  "id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
  "name": "Edge Tenant",
  "tags": ["iot", "prod"],
  "route": "edge",
  "metadata": { "region": "eu-west-1" },
  "status": "enabled",
  "created_by": "a5b6c7d8-e901-4fab-9bcd-123456789abc",
  "created_at": "2024-10-24T13:31:52Z"
}

List Domains

curl -X GET "http://localhost:9004/domains?limit=10&status=enabled" \
  -H "Authorization: Bearer <your_access_token>"
{
  "total": 2,
  "offset": 0,
  "limit": 10,
  "domains": [
    {
      "id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
      "name": "Edge Tenant",
      "route": "edge",
      "status": "enabled",
      "created_at": "2024-10-24T13:31:52Z"
    },
    {
      "id": "7f6a5b4c-3210-4fed-ba98-76543210fedc",
      "name": "Sandbox",
      "route": "sandbox",
      "status": "disabled",
      "created_at": "2024-10-10T08:12:04Z"
    }
  ]
}

Retrieve a Domain (with Roles)

curl -X GET "http://localhost:9004/domains/<domainID>?roles=true" \
  -H "Authorization: Bearer <your_access_token>"
{
  "id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
  "name": "Edge Tenant",
  "route": "edge",
  "status": "enabled",
  "roles": [
    {
      "role_id": "b83d25e7-6a49-4c2e-98c5-9323d4d9af7d",
      "role_name": "admin",
      "actions": ["manage_role_permission", "update_permission", "add_role_users_permission"]
    }
  ],
  "created_at": "2024-10-24T13:31:52Z",
  "updated_at": "2024-10-24T13:31:52Z"
}

Update a Domain

curl -X PATCH http://localhost:9004/domains/<domainID> \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Edge Operations",
    "tags": ["iot", "ops"],
    "metadata": { "region": "eu-west-1", "env": "prod" }
  }'

Enable, Disable, or Freeze a Domain

curl -X POST http://localhost:9004/domains/<domainID>/disable \
  -H "Authorization: Bearer <your_access_token>"

curl -X POST http://localhost:9004/domains/<domainID>/enable \
  -H "Authorization: Bearer <your_access_token>"

curl -X POST http://localhost:9004/domains/<domainID>/freeze \
  -H "Authorization: Bearer <your_access_token>"

Send an Invitation

curl -X POST http://localhost:9004/domains/<domainID>/invitations \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "invitee_user_id": "<userID>",
    "role_id": "<roleID>",
    "resend": false
  }'

List Domain or User Invitations

# For a specific domain
curl -X GET "http://localhost:9004/domains/<domainID>/invitations?limit=10&state=pending" \
  -H "Authorization: Bearer <your_access_token>"

# For the current user
curl -X GET "http://localhost:9004/invitations?limit=10" \
  -H "Authorization: Bearer <your_access_token>"
{
  "total": 1,
  "offset": 0,
  "limit": 10,
  "invitations": [
    {
      "invited_by": "a5b6c7d8-e901-4fab-9bcd-123456789abc",
      "invitee_user_id": "2c4d6e8f-0a12-4b3c-9d8e-7f6a5b4c3d2e",
      "domain_id": "f2b16e2c-5ad1-4c44-9c1b-0f862ec1c0c8",
      "domain_name": "Edge Tenant",
      "role_id": "b83d25e7-6a49-4c2e-98c5-9323d4d9af7d",
      "role_name": "admin",
      "actions": ["manage_role_permission", "update_permission"],
      "created_at": "2024-10-25T11:03:42Z"
    }
  ]
}

Accept, Reject, or Delete an Invitation

# Accept
curl -X POST http://localhost:9004/invitations/accept \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{ "domain_id": "<domainID>" }'

# Reject
curl -X POST http://localhost:9004/invitations/reject \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{ "domain_id": "<domainID>" }'

# Delete
curl -X DELETE http://localhost:9004/domains/<domainID>/invitations \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{ "user_id": "<inviteeUserID>" }'

Roles Management for Domains

Domain roles reuse the shared role manager. Supported operations:

Operation Description
create-role Create a new role for a domain
list-roles List all roles assigned to a domain
get-role Retrieve details for a specific domain role
update-role Update a domain role name
delete-role Delete a domain role
add-role-action Add one or more actions to a domain role
list-role-actions List all actions associated with a domain role
delete-role-action Remove a specific action from a domain role
delete-all-role-actions Remove all actions from a domain role
add-role-member Associate one or more members with a domain role
list-role-members List all members of a domain role
delete-role-member Remove one or more members from a domain role
delete-all-role-members Remove all members from a domain role
list-available-actions Retrieve the global list of available domain actions from the schema

Example: create a domain role

curl -X POST http://localhost:9004/domains/<domainID>/roles \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "role_name": "domain-editor",
    "optional_actions": ["update_permission", "read_permission"],
    "optional_members": ["<userID>"]
  }'

To discover allowed actions before creating roles, call:

curl -X GET http://localhost:9004/domains/roles/available-actions \
  -H "Authorization: Bearer <your_access_token>"

Implementation Details

  • Domains and invitations are persisted in PostgreSQL; migrations also create role tables with a domains_ prefix.
  • Redis caches domain status and route-to-ID lookups to speed up authorization.
  • Domain lifecycle events are published to the configured event store (MG_ES_URL).
  • Authorization and role checks are enforced via SpiceDB-backed policy service.
  • Optional HTTP callouts can be triggered before operations, using the MG_DOMAINS_CALLOUT_* settings.
  • Observability: Jaeger tracing, Prometheus metrics at /metrics, and a /health endpoint.

Domains Table

Column Type Description
id VARCHAR(36) UUID of the domain (primary key)
name VARCHAR(254) Human-readable domain name
tags TEXT[] Domain tags
metadata JSONB Arbitrary metadata
route VARCHAR(254) Unique domain route/alias
created_at TIMESTAMPTZ Creation timestamp
updated_at TIMESTAMPTZ Last update timestamp
updated_by VARCHAR(254) Actor who last updated the domain
created_by VARCHAR(254) Actor who created the domain
status SMALLINT 0 = enabled, 1 = disabled, 2 = freezed, 3 = deleted

Invitations Table

Column Type Description
invited_by VARCHAR(36) User who sent the invitation
invitee_user_id VARCHAR(36) User being invited
domain_id VARCHAR(36) Domain to join (FK to domains.id)
role_id VARCHAR(36) Role to grant on acceptance
created_at TIMESTAMPTZ Invitation creation time
updated_at TIMESTAMPTZ Last modification time
confirmed_at TIMESTAMPTZ When the invitation was accepted (if applicable)
rejected_at TIMESTAMPTZ When the invitation was rejected (if applicable)

Best Practices

  • Reserve concise, DNS-friendly route values for external-facing domains.
  • Use metadata and tags to capture environment, region, and ownership for filtering.
  • Prefer disable over delete when you need reversible off-boarding; use freeze for emergency locks by admins.
  • Keep role definitions minimal; grant only the actions needed and audit with list-role-members.
  • Clean up stale invitations regularly using the domain/user invitation listing endpoints.
  • When enabling callouts, narrow MG_DOMAINS_CALLOUT_OPERATIONS to the events you must observe.

Versioning and Health Check

The Domains service exposes /health with status and build metadata.

curl -X GET http://localhost:9004/health \
  -H "accept: application/health+json"

Example response:

{
  "status": "pass",
  "version": "0.18.0",
  "commit": "7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62",
  "description": "domains service",
  "build_time": "1970-01-01_00:00:00"
}

For full API coverage, see the Domains API documentation.