Skip to content

Lock Server Configuration and Operation#

The Janssen Lock Server is a Java Weld application that serves as the centralized Policy Retrieval Point (PRP) in a distributed Cedar-based authorization architecture. It connects ephemeral Cedarling instances to enterprise infrastructure by providing policy distribution, audit log collection, and OAuth-protected endpoints for secure communication.

Overview#

The Lock Server acts as the bridge between policy authoring tools (like Agama Lab Policy Designer) and distributed Cedarling instances, ensuring consistent policy enforcement across the network while maintaining high availability and security.

Key Capabilities#

  • Policy Distribution: Centralized management and distribution of Cedar policies
  • Policy Updates: Efficient policy change management and distribution
  • Audit Collection: Centralized logging of authorization decisions and system events
  • OAuth Security: Comprehensive OAuth 2.0 protection for all endpoints
  • Flexible Deployment: Standalone or integrated with Jans Auth Server
  • Management Interfaces: CLI, TUI, and REST API for administration

Architecture#

High-Level Components#

graph TB
    subgraph "Policy Authoring"
        AL[Agama Lab Policy Designer]
        GH[GitHub Repository]
    end

    subgraph "Lock Server Infrastructure"
        LS[Lock Server]
        CL[Embedded Cedarling]
        PS[Policy Store Cache]
        AL_LOG[Audit Logs]
    end

    subgraph "OAuth Infrastructure"
        AS[Jans Auth Server]
        DCR[Dynamic Client Registration]
    end

    subgraph "Cedarling Clients"
        C1[Cedarling Client 1]
        C2[Cedarling Client 2]
        CN[Cedarling Client N]
    end

    AL --> GH
    GH --> PS
    C1 --> DCR
    C2 --> DCR
    CN --> DCR
    DCR --> AS
    C1 -.->|OAuth Token| LS
    C2 -.->|OAuth Token| LS
    CN -.->|OAuth Token| LS
    LS --> CL
    LS --> PS
    LS --> AL_LOG
    C1 -.->|Audit Data| LS
    C2 -.->|Audit Data| LS
    CN -.->|Audit Data| LS

Internal Architecture#

The Lock Server consists of several layers:

  • Web Layer: REST endpoints for policy and audit operations
  • Security Layer: OAuth token validation and Cedarling authorization
  • Business Logic: Policy store management, audit collection, client management
  • Data Layer: Policy store cache, audit storage, client registry
  • Integration Layer: Embedded Cedarling, external policy sources

Installation and Deployment#

Deployment Options#

The Lock Server supports two primary deployment models:

Standalone Deployment#

Deploy Lock Server as an independent web application:

# docker-compose.yml
version: '3.8'
services:
  lock-server:
    image: janssenproject/lock-server:latest
    ports:
      - "8080:8080"
    environment:
      - LOCK_SERVER_POLICY_STORE_SOURCE=github
      - LOCK_SERVER_GITHUB_REPO=org/policy-repo
      - LOCK_SERVER_OAUTH_ISSUER=https://auth.example.com
      - LOCK_SERVER_JWKS_URI=https://auth.example.com/.well-known/jwks
    volumes:
      - ./config:/opt/jans/lock-server/config
      - ./logs:/opt/jans/lock-server/logs
    networks:
      - jans-network

  redis:
    image: redis:alpine
    networks:
      - jans-network

networks:
  jans-network:
    driver: bridge

Integrated Deployment#

Deploy Lock Server embedded within Jans Auth Server:

# Jans Auth Server configuration
services:
  jans-auth:
    image: janssenproject/jans-auth-server:latest
    environment:
      - JANS_LOCK_SERVER_ENABLED=true
      - JANS_LOCK_SERVER_POLICY_STORE_SOURCE=local
      - JANS_LOCK_SERVER_EMBEDDED_MODE=true
    volumes:
      - ./lock-server-config:/opt/jans/jetty/jans-auth/custom/lock-server
      - ./policy-stores:/opt/jans/lock-server/policy-stores

High Availability Setup#

For production deployments requiring high availability:

# HA deployment with load balancer
services:
  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - lock-server-1
      - lock-server-2

  lock-server-1:
    image: janssenproject/lock-server:latest
    environment:
      - LOCK_SERVER_INSTANCE_ID=lock-server-1
      - LOCK_SERVER_REDIS_URL=redis://redis:6379
    depends_on:
      - redis

  lock-server-2:
    image: janssenproject/lock-server:latest
    environment:
      - LOCK_SERVER_INSTANCE_ID=lock-server-2
      - LOCK_SERVER_REDIS_URL=redis://redis:6379
    depends_on:
      - redis

  redis:
    image: redis:alpine
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

volumes:
  redis-data:

Installation Steps#

  1. Prerequisites
  2. Java 11 or higher
  3. Jans Auth Server (for OAuth services)
  4. Redis (for HA deployments)

  5. Download and Extract

    wget https://github.com/JanssenProject/jans/releases/latest/download/lock-server.tar.gz
    tar -xzf lock-server.tar.gz
    cd lock-server
    

  6. Configure Environment

    cp config/lock-server.properties.template config/lock-server.properties
    # Edit configuration file with your settings
    

  7. Start Lock Server

    ./bin/start-lock-server.sh
    

Configuration#

Core Configuration Properties#

The Lock Server uses a properties file for configuration:

# Lock Server Configuration
lock.server.host=0.0.0.0
lock.server.port=8080
lock.server.context.path=/

# OAuth Configuration
lock.server.oauth.issuer=https://auth.example.com
lock.server.oauth.jwks.uri=https://auth.example.com/.well-known/jwks
lock.server.oauth.token.validation.enabled=true

# Policy Store Configuration
lock.server.policy.store.source=github
lock.server.policy.store.github.repo=organization/policy-repo
lock.server.policy.store.github.branch=main
lock.server.policy.store.github.token=${GITHUB_TOKEN}
lock.server.policy.store.cache.ttl=300

# Cedarling Configuration
lock.server.cedarling.policy.store.uri=file:///opt/jans/lock-server/policies/lock-server-policies.json
lock.server.cedarling.log.level=INFO

# Audit Configuration
lock.server.audit.enabled=true
lock.server.audit.storage=file
lock.server.audit.file.path=/opt/jans/lock-server/logs/lock_server_audit.log
lock.server.audit.rdbms.enabled=false

# Policy Update Configuration
lock.server.policy.update.enabled=true
lock.server.policy.update.check.interval=60

# Logging Configuration
lock.server.log.level=INFO
lock.server.log.config.file=/opt/jans/lock-server/logs/lock_server_config.log
lock.server.log.jwt.status.file=/opt/jans/lock-server/logs/lock_server_jwt_status.log

TRACE Configuration#

The traceConfiguration block of the Lock Server dynamic configuration (jansConfDyn) controls the TRACE evidence-ingestion feature: which OAuth clients may submit or read evidence for which evidence domain, lateness policy, and request limits enforced before any cryptographic verification. See TRACE Evidence for the feature description and API.

Property Type Default Meaning
enabled boolean true When false, every TRACE endpoint returns a structured invalid_request error and the receipt repair timer does not run.
defaultEvidenceDomainId string null Evidence domain used for a submitting/reading client that has no explicit entry in clientDomainBindings.
defaultAllowedProducerIds array [] Producer ids a client without a binding may submit records for in the default evidence domain. Empty means such a client can submit nothing (producer_not_allowed). Read and admin paths are unaffected.
clientDomainBindings array [] List of { clientId, evidenceDomainId, allowedProducerIds[] } bindings. A client without a binding and without defaultEvidenceDomainId set is rejected with client_not_bound. allowedProducerIds may contain "*" to allow any producer.
latenessThresholdSeconds integer 300 Seconds after signed_at a record may still be accepted before it is flagged late_flag: true.
policyMismatchGraceSeconds integer 300 Seconds after the last Lock node stops serving a policy store release during which records judged under it are not flagged policy_mismatch_flag. The check uses the larger of this and latenessThresholdSeconds, plus about 130 seconds for update and cache lag. See TRACE.
policyReleaseRetentionDays integer 30 Days a policy store release no node serves any more is kept before it is deleted; never less than the check's acceptance window.
maxFutureSkewSeconds integer 300 Seconds signed_at may be ahead of Lock's clock. A later signed_at is rejected with invalid_assertion (signed_at_in_future).
maxRequestBytes integer 262144 Maximum accepted TRACE request body size, in bytes.
maxJsonDepth integer 32 Maximum accepted JSON nesting depth of a TRACE assertion.
maxStringLength integer 8192 Maximum accepted JSON string length (UTF-16 units) in a TRACE assertion.
maxArrayLength integer 256 Maximum accepted JSON array length in a TRACE assertion.
maxObjectMembers integer 256 Maximum accepted JSON object member count in a TRACE assertion.
receiptAllocationRetryLimit integer 8 Maximum retries when allocating the next receipt-chain sequence number under multi-node contention.
correlationRetryLimit integer 3 Maximum retries when a neighbor-flag update after a record insert hits a version conflict. After the limit Lock logs a warning and gives up on that update; the request still succeeds.
receiptRepairIntervalSeconds integer 300 Interval between runs of the receipt repair timer, which settles stale PENDING receipts.
pendingReceiptTimeoutSeconds integer 120 Seconds a PENDING receipt may remain unresolved before the repair timer marks it COMMITTED or VOID.
maxBulkRecords integer 100 Maximum number of assertions accepted in one POST /audit/trace/bulk request.
maxBulkRequestBytes integer 4194304 Maximum total body size, in bytes, buffered for one POST /audit/trace/bulk request. Independent of maxRequestBytes/maxBulkRecords, and always clamped to 16777216 regardless of configuration.
chainRegistrationMode string PRE_REGISTERED How producer chains come to exist. PRE_REGISTERED: a chain must be registered through the admin API before its records are accepted. FIRST_OBSERVED: a record with sequence_number 1 and the all-zero prev_record_hash on an unregistered chain registers the chain, after the key, event-kind and signature checks pass. Any other record on an unregistered chain is still rejected with chain_not_registered. A value that is not a mode name is treated as PRE_REGISTERED and logged once at WARN. Changing the mode affects only later submissions; existing chains are not rewritten.
cryptoProvider string JAVA TRACE cryptography implementation. JAVA: BouncyCastle, in-process. NATIVE: jans-trace-core through the jans-trace-java binding. Both produce the same digests, thumbprints and receipt hashes, so switching does not invalidate the stored receipt chain. When the selected provider is not available, every TRACE submission fails with crypto_unavailable; Lock never falls back to the other provider. A value that is not a provider name is treated as JAVA and logged once at WARN. See TRACE.

Every numeric limit above falls back to its default when configured with a value <= 0.

Policy Store Sources#

The Lock Server supports multiple policy store sources:

GitHub Repository#

lock.server.policy.store.source=github
lock.server.policy.store.github.repo=organization/policy-repo
lock.server.policy.store.github.branch=main
lock.server.policy.store.github.path=policy-stores/
lock.server.policy.store.github.token=${GITHUB_TOKEN}

Local File System#

lock.server.policy.store.source=file
lock.server.policy.store.file.path=/opt/jans/lock-server/policy-stores/
lock.server.policy.store.file.watch.enabled=true

HTTP Endpoint#

lock.server.policy.store.source=http
lock.server.policy.store.http.base.url=https://policy-server.example.com/api/v1/
lock.server.policy.store.http.auth.type=bearer
lock.server.policy.store.http.auth.token=${POLICY_SERVER_TOKEN}

REST API Endpoints#

The Lock Server provides several REST API endpoints for different operations:

Policy Store Endpoints#

Get Policy Store#

GET /policy-store/{id}
Authorization: Bearer <access_token>

Response:

{
  "cedar_version": "v4.0.0",
  "policy_store": {
    "name": "Application Policy Store",
    "description": "Policies for application authorization",
    "policies": { ... },
    "schema": { ... },
    "trusted_issuers": { ... }
  }
}

List Policy Stores#

GET /policy-stores
Authorization: Bearer <access_token>

Response:

{
  "policy_stores": [
    {
      "id": "app-policies",
      "name": "Application Policies",
      "description": "Main application policy store",
      "version": "1.2.3",
      "last_updated": "2024-01-01T12:00:00Z"
    }
  ]
}

Audit Endpoints#

Submit Audit Logs#

POST /api/v1/audit/log
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "creation_date": "2026-03-23T11:50:37.504Z",
  "event_time": "2026-03-23T11:50:37.504Z",
  "service": "my_app",
  "node_name": "0195c6f2-8d1a-7c3e-9b4f-2a6d8e0f1b3c",
  "event_type": "Decision",
  "severity_level": "INFO",
  "action": "Jans::Action::\"Update\"",
  "decision_result": "ALLOW",
  "requested_resource": "Jans::Issue::\"random_id\"",
  "principal_id": "Jans::User, Jans::Workload",
  "client_id": "lock-client-123",
  "context_information": {
    "request_id": "0195c6f2-8d1a-7c3e-9b4f-2a6d8e0f1b3e",
    "policystore_id": "a1bf63d5a5e4a0b7d0d5c9e3",
    "policystore_version": "1.0.0",
    "diagnostics": { "reason": [], "errors": [] },
    "decision_time_micro_sec": 42
  }
}

This is the shape Cedarling sends. POST /audit/log/bulk takes an array of the same objects. Both need the https://jans.io/oauth/lock/log.write scope. Lock also accepts the camelCase member names it returns (creationDate, eventTime, nodeName, contextInformation, and so on). contextInformation is stored as a flat string map: a string value is kept as is, and an object, array, number or boolean value is stored as its JSON text, as on the gRPC path.

Search Audit Logs#

Config API serves stored decision logs at GET /jans-config-api/lock/audit/log/search. eventStartDate and eventEndDate (ISO 8601) are required. Optional exact-match filters:

Parameter Matches
requestId Cedarling request_id of the decision
policyStoreId Policy store id used for the decision
policyStoreVersion Policy store version used for the decision

A stored entry takes these from the request_id, policystore_id and policystore_version keys of contextInformation when present, and otherwise from the entry's own requestId, policyStoreId and policyStoreVersion. A request_id longer than 64 characters or a policy store value longer than 255 characters is not indexed. Entries stored before this release are not indexed and match only the date range.

Submit Health Status#

POST /audit/health
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "pdp_id": "cedarling-001",
  "timestamp": "2024-01-01T12:00:00Z",
  "status": "healthy",
  "policy_store_version": "1.2.3",
  "uptime_seconds": 86400,
  "memory_usage_mb": 128,
  "cpu_usage_percent": 15.5
}

Submit Telemetry Data#

POST /audit/telemetry
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "pdp_id": "cedarling-001",
  "timestamp": "2024-01-01T12:00:00Z",
  "metrics": {
    "total_requests": 1000,
    "successful_requests": 950,
    "failed_requests": 50,
    "average_response_time_ms": 12.5,
    "policy_evaluations": 1000,
    "cache_hits": 800,
    "cache_misses": 200
  }
}

Well-Known Configuration#

Lock Server Configuration#

GET /.well-known/lock-server-configuration

Response:

{
  "version": "1.0",
  "issuer": "lock-server.example.com",
  "audit": {
    "health_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/health",
    "health_bulk_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/health/bulk",
    "log_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/log",
    "log_bulk_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/log/bulk",
    "telemetry_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/telemetry",
    "telemetry_bulk_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/telemetry/bulk",
    "trace_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/trace",
    "trace_bulk_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/trace/bulk",
    "trace_record_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/trace/records",
    "trace_execution_endpoint": "https://lock-server.example.com/jans-lock/api/v1/audit/trace/executions"
  },
  "config": {
    "policy_endpoint": "https://lock-server.example.com/jans-lock/api/v1/policy"
  }
}

The trace_* members appear only when TRACE is enabled.

OAuth Security#

Scope-Based Access Control#

The Lock Server uses OAuth 2.0 scopes to control access to different endpoints:

Scope Endpoints Description
https://jans.io/oauth/lock/policy-store.read /policy-store/*, /policy-stores Read access to policy stores
https://jans.io/oauth/lock/log.write /audit/logs Submit authorization decision logs
https://jans.io/oauth/lock/health.write /audit/health Submit health status information
https://jans.io/oauth/lock/telemetry.write /audit/telemetry Submit telemetry and metrics data
https://jans.io/oauth/lock/trace.write /audit/trace Submit TRACE evidence records
https://jans.io/oauth/lock/trace.readonly /audit/trace/records, /audit/trace/records/*, /audit/trace/executions/* Read and search TRACE records and executions
https://jans.io/oauth/lock/trace.admin /audit/trace/admin/* Manage TRACE producer keys and chains

Logging and Monitoring#

Log Files#

The Lock Server generates several log files for different purposes:

Configuration Log (lock_server_config.log)#

Records configuration changes and system events:

2024-01-01 12:00:00 INFO  [ConfigService] Policy store configuration updated: app-policies
2024-01-01 12:01:00 INFO  [ConfigService] Trusted issuer added: enterprise_idp
2024-01-01 12:02:00 WARN  [ConfigService] Policy store cache miss for: test-policies
2024-01-01 12:03:00 ERROR [ConfigService] Failed to fetch policy store from GitHub: network timeout

Audit Log (lock_server_audit.log)#

Stores authorization decisions and audit events:

{
  "timestamp": "2024-01-01T12:00:00Z",
  "request_id": "req-123456",
  "log_kind": "Decision",
  "pdp_id": "cedarling-001",
  "policy_store_id": "app-policies",
  "decision": "ALLOW",
  "principal": "Jans::User::\"user123\"",
  "action": "Jans::Action::\"read\"",
  "resource": "Jans::Application::\"app001\"",
  "decision_time_ms": 15
}

JWT Status Log (lock_server_jwt_status.log)#

Tracks JWT token validation and processing:

2024-01-01 12:00:00 INFO  [JWTValidator] Token validated successfully for client: client123
2024-01-01 12:01:00 WARN  [JWTValidator] Token expired for client: client456
2024-01-01 12:02:00 ERROR [JWTValidator] Invalid signature for token from issuer: https://malicious.com

RDBMS Audit Storage#

With auditPersistenceMode set to internal, Lock stores decision logs in the jansLogEntry table of the Janssen database (entries under ou=log of the audit base DN). With config-api, Lock forwards them to Config API, which stores them in the same table.

Column Source
inum Generated by Lock
creationDate, eventTime creation_date, event_time
jansService, jansNodeName service, node_name
eventType, severityLevel event_type, severity_level
actionName, decisionResult, requestedResource action, decision_result, requested_resource
principalId, clientId, jti principal_id, client_id, jti
contextInformation context_information, as a JSON object of strings
jansRequestId, jansPolicyStoreId, jansPolicyStoreVersion Indexed copies of request_id, policystore_id, policystore_version (see Search Audit Logs)

eventTime, jansRequestId, jansPolicyStoreId and jansPolicyStoreVersion are indexed.

Upgrading an Existing Deployment#

The audit log and TRACE search filters need new columns and indexes, and the policy release check needs the jansTracePolicyRelease table. Container and Kubernetes deployments get them automatically: the persistence loader adds missing columns and indexes on its next run. An existing VM install needs them added once, by hand. Back up the database first.

ALTER TABLE "jansLogEntry" ADD COLUMN "jansRequestId" VARCHAR(64);
ALTER TABLE "jansLogEntry" ADD COLUMN "jansPolicyStoreId" VARCHAR(255);
ALTER TABLE "jansLogEntry" ADD COLUMN "jansPolicyStoreVersion" VARCHAR(255);
CREATE INDEX "jansLogEntry_jansRequestId" ON "jansLogEntry" ("jansRequestId");
CREATE INDEX "jansLogEntry_jansPolicyStoreId" ON "jansLogEntry" ("jansPolicyStoreId");
CREATE INDEX "jansLogEntry_jansPolicyStoreVersion" ON "jansLogEntry" ("jansPolicyStoreVersion");

ALTER TABLE "jansTraceRecord" ADD COLUMN "jansTracePolicyStoreId" VARCHAR(255);
ALTER TABLE "jansTraceRecord" ADD COLUMN "jansTracePolicyStoreVersion" VARCHAR(255);
ALTER TABLE "jansTraceRecord" ADD COLUMN "jansTraceBundleHash" VARCHAR(255);
ALTER TABLE "jansTraceRecord" ADD COLUMN "jansTracePolicyMismatch" BOOLEAN;
ALTER TABLE "jansTraceRecord" ADD COLUMN "jansTraceReservedMembers" JSONB;
CREATE INDEX "jansTraceRecord_jansTracePolicyStoreId" ON "jansTraceRecord" ("jansTracePolicyStoreId");
CREATE INDEX "jansTraceRecord_jansTracePolicyStoreVersion" ON "jansTraceRecord" ("jansTracePolicyStoreVersion");
CREATE INDEX "jansTraceRecord_jansTraceBundleHash" ON "jansTraceRecord" ("jansTraceBundleHash");

CREATE TABLE "jansTracePolicyRelease" (
    doc_id VARCHAR(64) NOT NULL UNIQUE,
    "objectClass" VARCHAR(48),
    dn VARCHAR(128),
    "jansId" VARCHAR(128),
    "jansTracePolicyStoreId" VARCHAR(255),
    "jansTraceBundleHash" VARCHAR(255),
    "jansTracePolicyStoreVersion" VARCHAR(255),
    "jansTraceFirstServedAtMs" BIGINT,
    "jansTraceLastServedAtMs" BIGINT,
    "jansVersion" BIGINT,
    PRIMARY KEY (doc_id)
);
CREATE INDEX "jansTracePolicyRelease_jansId" ON "jansTracePolicyRelease" ("jansId");
CREATE INDEX "jansTracePolicyRelease_jansTracePolicyStoreId" ON "jansTracePolicyRelease" ("jansTracePolicyStoreId");
CREATE INDEX "jansTracePolicyRelease_jansTraceLastServedAtMs" ON "jansTracePolicyRelease" ("jansTraceLastServedAtMs");
ALTER TABLE jansLogEntry ADD COLUMN jansRequestId VARCHAR(64);
ALTER TABLE jansLogEntry ADD COLUMN jansPolicyStoreId VARCHAR(255);
ALTER TABLE jansLogEntry ADD COLUMN jansPolicyStoreVersion VARCHAR(255);
ALTER TABLE jansLogEntry ADD INDEX jansLogEntry_jansRequestId (jansRequestId);
ALTER TABLE jansLogEntry ADD INDEX jansLogEntry_jansPolicyStoreId (jansPolicyStoreId);
ALTER TABLE jansLogEntry ADD INDEX jansLogEntry_jansPolicyStoreVersion (jansPolicyStoreVersion);

ALTER TABLE jansTraceRecord ADD COLUMN jansTracePolicyStoreId VARCHAR(255);
ALTER TABLE jansTraceRecord ADD COLUMN jansTracePolicyStoreVersion VARCHAR(255);
ALTER TABLE jansTraceRecord ADD COLUMN jansTraceBundleHash VARCHAR(255);
ALTER TABLE jansTraceRecord ADD COLUMN jansTracePolicyMismatch SMALLINT;
ALTER TABLE jansTraceRecord ADD COLUMN jansTraceReservedMembers JSON;
ALTER TABLE jansTraceRecord ADD INDEX jansTraceRecord_jansTracePolicyStoreId (jansTracePolicyStoreId);
ALTER TABLE jansTraceRecord ADD INDEX jansTraceRecord_jansTracePolicyStoreVersion (jansTracePolicyStoreVersion);
ALTER TABLE jansTraceRecord ADD INDEX jansTraceRecord_jansTraceBundleHash (jansTraceBundleHash);

CREATE TABLE jansTracePolicyRelease (
    doc_id VARCHAR(64) NOT NULL UNIQUE,
    objectClass VARCHAR(48),
    dn VARCHAR(128),
    jansId VARCHAR(128),
    jansTracePolicyStoreId VARCHAR(255),
    jansTraceBundleHash VARCHAR(255),
    jansTracePolicyStoreVersion VARCHAR(255),
    jansTraceFirstServedAtMs BIGINT,
    jansTraceLastServedAtMs BIGINT,
    jansVersion BIGINT,
    PRIMARY KEY (doc_id),
    INDEX jansTracePolicyRelease_jansId (jansId),
    INDEX jansTracePolicyRelease_jansTracePolicyStoreId (jansTracePolicyStoreId),
    INDEX jansTracePolicyRelease_jansTraceLastServedAtMs (jansTraceLastServedAtMs)
);

Records and log entries stored before the upgrade have empty values in the new columns, so release search and log filters do not return them.

Metrics and Monitoring#

The Lock Server exposes metrics for monitoring:

  • Policy Store Metrics: Cache hit/miss rates, fetch times, update frequencies
  • Authorization Metrics: Request rates, decision times, success/failure ratios
  • Client Metrics: Active connections, request patterns, error rates
  • System Metrics: Memory usage, CPU utilization, response times

CLI Management#

Jans CLI Commands#

The Lock Server can be managed using Jans CLI commands:

Policy Store Management#

# List policy stores
jans-cli --operation-id get-lock-policy-stores

# Get specific policy store
jans-cli --operation-id get-lock-policy-store --url-suffix "app-policies"

# Update policy store configuration
jans-cli --operation-id put-lock-policy-store --url-suffix "app-policies" \
  --data '{"source": "github", "repository": "org/new-repo"}'

# Delete policy store
jans-cli --operation-id delete-lock-policy-store --url-suffix "app-policies"

Client Management#

# List connected Cedarling clients
jans-cli --operation-id get-lock-clients

# Get client details
jans-cli --operation-id get-lock-client --url-suffix "client123"

# Search clients by username
jans-cli --operation-id get-lock-clients --query "username=john.doe"

# View client authorization activity
jans-cli --operation-id get-lock-client-activity --url-suffix "client123" \
  --query "start_date=2024-01-01&end_date=2024-01-31"

Metrics and Monitoring#

# Get authorization metrics
jans-cli --operation-id get-lock-metrics --query "metric=authorization_requests&period=daily"

# Get system health
jans-cli --operation-id get-lock-health

# Get audit log summary
jans-cli --operation-id get-lock-audit-summary --query "start_date=2024-01-01"

TUI Interface#

The Text-based User Interface provides an interactive way to manage Lock Server:

  1. Access TUI: sudo /opt/jans/bin/jans-tui.py
  2. Navigate to Lock Server: Lock Server > Configuration
  3. Available Sections:
  4. Policy Store Management
  5. Client Registry
  6. Audit Logs
  7. System Metrics
  8. Configuration Settings

Troubleshooting#

Common Issues#

Policy Store Not Loading#

Symptoms: Cedarling clients cannot retrieve policy stores Causes: - Invalid policy store source configuration - Network connectivity issues - Authentication failures with external sources

Solutions:

# Check policy store configuration
jans-cli --operation-id get-lock-policy-store-config

# Test policy store connectivity
curl -H "Authorization: Bearer <token>" \
  https://lock-server.example.com/policy-store/app-policies

# Check logs for errors
tail -f /opt/jans/lock-server/logs/lock_server_config.log

OAuth Token Validation Failures#

Symptoms: Clients receive 401 Unauthorized responses Causes: - Expired or invalid access tokens - Incorrect JWKS URI configuration - Clock synchronization issues

Solutions:

# Verify JWKS URI configuration
jans-cli --operation-id get-lock-oauth-config

# Check JWT status logs
tail -f /opt/jans/lock-server/logs/lock_server_jwt_status.log

# Test token validation manually
curl -H "Authorization: Bearer <token>" \
  https://lock-server.example.com/.well-known/lock-master-configuration

Policy Update Issues#

Symptoms: Cedarling clients not receiving latest policy updates Causes: - Policy store cache configuration issues - Network connectivity problems - Policy source synchronization failures

Solutions:

# Check policy store cache status
jans-cli --operation-id get-lock-policy-cache-status

# Force policy store refresh
jans-cli --operation-id post-lock-policy-refresh --url-suffix "app-policies"

# Monitor policy update logs
tail -f /opt/jans/lock-server/logs/lock_server_config.log

Performance Optimization#

Policy Store Caching#

  • Increase cache TTL for stable policy stores
  • Use Redis for distributed caching in HA setups
  • Monitor cache hit rates and adjust accordingly

Database Optimization#

  • Create appropriate indexes for audit log queries
  • Implement log rotation and archival policies
  • Use connection pooling for database access

Network Optimization#

  • Use CDN for policy store distribution
  • Implement compression for large policy stores
  • Configure appropriate timeout values

Security Considerations#

Production Deployment Security#

  1. TLS Configuration: Always use HTTPS in production
  2. Token Security: Implement proper token rotation and validation
  3. Network Security: Use firewalls and network segmentation
  4. Audit Security: Protect audit logs from tampering
  5. Access Control: Implement least-privilege access principles

Security Best Practices#

  • Regular security updates and patches
  • Monitoring and alerting for security events
  • Regular audit log reviews
  • Secure backup and recovery procedures
  • Incident response planning

API Reference#

For complete API documentation, see the Lock Server OpenAPI Specification.

See Also#