Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG/feat_deploy_opa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Changelog — feat_deploy_opa

## Features

- **deploy/opa**: add OPA + KMS docker-compose stack with `--disable-telemetry` on OPA ([#995](https://github.com/Cosmian/kms/pull/995))
- **deploy/rbac**: add full RBAC stack — step-ca TLS, Keycloak IDP, OPA, and KMS with JWT auth ([#995](https://github.com/Cosmian/kms/pull/995))
- **deploy/rbac**: add `keycloak/realm-export.json` with `kms` realm, 4 pre-configured users/roles, and audience mapper for `cosmian-kms` client ([#995](https://github.com/Cosmian/kms/pull/995))
- **deploy/rbac**: add `test.sh` smoke-test script covering token issuance, role validation, and authenticated KMS calls ([#995](https://github.com/Cosmian/kms/pull/995))

## Bug Fixes

- **jwt**: fix `UserClaim` serde deserialization failing with `missing field 'aud'` when tokens omit the audience claim — add `#[serde(default)]` to the `aud` field ([#995](https://github.com/Cosmian/kms/pull/995))
5 changes: 5 additions & 0 deletions CHANGELOG/feat_rbac_is_back.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog — feat_rbac_is_back

## Features

- **deploy/opa**: add Cosmian KMS service to `deploy/opa/docker-compose.yml` — SQLite backend, embedded Regorus RBAC enabled, shares the same Rego policy bundle as the OPA sidecar container; disable OPA anonymous telemetry (`--disable-telemetry`).
2 changes: 1 addition & 1 deletion crate/server/src/middlewares/jwt/jwt_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub(crate) struct UserClaim {
pub email: Option<String>,
pub iss: Option<String>,
pub sub: Option<String>,
#[serde(deserialize_with = "deserialize_aud")]
#[serde(default, deserialize_with = "deserialize_aud")]
pub aud: Option<Vec<String>>,
pub iat: Option<usize>,
pub exp: Option<usize>,
Expand Down
94 changes: 94 additions & 0 deletions deploy/opa/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# ===========================================================================
# Cosmian KMS — OPA RBAC demo stack
#
# Services:
# - OPA (Open Policy Agent — standalone policy evaluation server for
# external inspection / debugging on port 8181)
# - KMS (Cosmian KMS — uses the same Rego policy bundle via its embedded
# Regorus engine; SQLite backend for simplicity)
#
# Usage:
# docker compose up -d
# # KMS HTTP API
# curl http://localhost:9998/health
# # OPA policy evaluation
# curl -s -X POST http://localhost:8181/v1/data/cosmian/kms/rbac/allow \
# -H "Content-Type: application/json" \
# -d '{"input":{"subject":{"roles":["admin"]},"action":{"operation":"create"}}}'
#
# RBAC notes:
# - Policy bundle: ./opa/policy/default_rbac.rego + data.json
# - Roles: admin | operator | auditor | readonly
# - KMS_FORCE_DEFAULT_USERNAME=true lets the default "admin" identity work
# without an IdP; add JWT/mTLS auth for production.
# ===========================================================================
name: cosmian-kms-opa

networks:
kms-net:
driver: bridge

volumes:
kms-data:

services:
# ===========================================================================
# OPA (Open Policy Agent — standalone REST policy server)
# ===========================================================================
opa:
image: ${OPA_IMAGE:-openpolicyagent/opa:0.68.0}
hostname: opa
networks:
- kms-net
ports:
- "8181:8181"
command:
- run
- --server
- --addr=0.0.0.0:8181
- --log-level=debug
- --disable-telemetry
- /policies/default_rbac.rego
- /policies/data.json
volumes:
- ./opa/policy/default_rbac.rego:/policies/default_rbac.rego:ro
- ./opa/policy/data.json:/policies/data.json:ro
healthcheck:
test: ["CMD", "/opa", "eval", "true"]
interval: 10s
timeout: 5s
retries: 3
start_period: 10s

# ===========================================================================
# Cosmian KMS Server
# ===========================================================================
kms:
image: ${KMS_IMAGE:-ghcr.io/cosmian/kms:latest}
hostname: kms
networks:
- kms-net
ports:
- "${KMS_PORT:-9998}:9998"
environment:
# SQLite backend — no external database required
- KMS_DATABASE_TYPE=sqlite
- KMS_SQLITE_PATH=/tmp/kms-data
# RBAC — use the same Rego bundle as the OPA container above
- KMS_RBAC_ENABLED=true
- KMS_RBAC_BUNDLE_PATH=/policies
# Allow the built-in "admin" identity when no IdP is configured
- KMS_FORCE_DEFAULT_USERNAME=true
- RUST_LOG=${KMS_LOG_LEVEL:-info,cosmian_kms=debug}
volumes:
- ./opa/policy:/policies:ro
- kms-data:/tmp/kms-data
depends_on:
opa:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "echo > /dev/tcp/localhost/9998"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
14 changes: 14 additions & 0 deletions deploy/opa/opa/policy/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"cosmian": {
"kms": {
"rbac": {
"role_assignments": {
"admin@cosmian.com": ["admin"],
"operator@cosmian.com": ["operator"],
"auditor@cosmian.com": ["auditor"],
"readonly@cosmian.com": ["readonly"]
}
}
}
}
}
85 changes: 85 additions & 0 deletions deploy/opa/opa/policy/default_rbac.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Cosmian KMS — Default RBAC Policy
#
# This policy implements role-based access control aligned with NIST SP 800-162.
# It defines four default roles: administrator, operator, auditor, and readonly.
#
# Input schema (NIST SP 800-162 attributes):
# input.subject.user_id — authenticated user identifier
# input.subject.roles — list of assigned roles
# input.subject.is_owner — true if user owns the target object
# input.subject.is_privileged — true if user is in the privileged_users list
# input.action.operation — KMIP operation (lowercase)
# input.resource.* — target object attributes
# input.environment.* — contextual attributes (reserved)
#
# Decision: data.cosmian.kms.rbac.allow = true | false

package cosmian.kms.rbac

import rego.v1

default allow := false

# ── Administrator ────────────────────────────────────────────────────────
# Full access to all operations.
allow if {
some role in input.subject.roles
role == "admin"
}

# ── Operator ─────────────────────────────────────────────────────────────
# All key management and cryptographic operations.
allow if {
some role in input.subject.roles
role == "operator"
input.action.operation in operator_operations
}

operator_operations := {
"create",
"certify",
"decrypt",
"derive_key",
"destroy",
"encrypt",
"export",
"get",
"get_attributes",
"hash",
"import",
"locate",
"mac",
"revoke",
"rekey",
"sign",
"signature_verify",
"validate",
}

# ── Auditor ──────────────────────────────────────────────────────────────
# Read-only access for inspection and compliance auditing.
allow if {
some role in input.subject.roles
role == "auditor"
input.action.operation in auditor_operations
}

auditor_operations := {
"get",
"get_attributes",
"locate",
"validate",
}

# ── Read-Only ────────────────────────────────────────────────────────────
# Minimal access: can only list and inspect metadata.
allow if {
some role in input.subject.roles
role == "readonly"
input.action.operation in readonly_operations
}

readonly_operations := {
"get_attributes",
"locate",
}
2 changes: 2 additions & 0 deletions deploy/rbac/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# TLS certificates issued by step-ca at runtime — do not commit
certs/
Loading
Loading