loki-mode 5.35.0 → 5.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: Multi-agent autonomous startup system. Triggers on "Loki Mode". Takes PRD to deployed product with zero human intervention. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v5.35.0
6
+ # Loki Mode v5.37.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -260,4 +260,4 @@ The following features are documented in skill modules but not yet fully automat
260
260
  | Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
261
261
  | Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
262
262
 
263
- **v5.35.0 | checkpoint/restore, GitHub Action provider-agnostic | ~260 lines core**
263
+ **v5.37.0 | enterprise: TLS, OIDC/SSO, audit default-on, budget controls, watchdog, secrets, OpenClaw | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 5.35.0
1
+ 5.37.0
package/autonomy/loki CHANGED
@@ -322,8 +322,10 @@ show_help() {
322
322
  echo " compound [cmd] Knowledge compounding (list|show|search|run|stats)"
323
323
  echo " council [cmd] Completion council (status|verdicts|convergence|force-review|report)"
324
324
  echo " dogfood Show self-development statistics"
325
+ echo " secrets [cmd] API key status and validation (status|validate)"
325
326
  echo " reset [target] Reset session state (all|retries|failed)"
326
327
  echo " doctor [--json] Check system prerequisites"
328
+ echo " watchdog [cmd] Process health monitoring (status|help)"
327
329
  echo " version Show version"
328
330
  echo " help Show this help"
329
331
  echo ""
@@ -1324,8 +1326,10 @@ cmd_dashboard_help() {
1324
1326
  echo " help Show this help"
1325
1327
  echo ""
1326
1328
  echo "Options for 'start':"
1327
- echo " --port PORT Port to listen on (default: $DASHBOARD_DEFAULT_PORT)"
1328
- echo " --host HOST Host to bind to (default: $DASHBOARD_DEFAULT_HOST)"
1329
+ echo " --port PORT Port to listen on (default: $DASHBOARD_DEFAULT_PORT)"
1330
+ echo " --host HOST Host to bind to (default: $DASHBOARD_DEFAULT_HOST)"
1331
+ echo " --tls-cert PATH Path to PEM certificate (enables HTTPS)"
1332
+ echo " --tls-key PATH Path to PEM private key (enables HTTPS)"
1329
1333
  echo ""
1330
1334
  echo "Options for 'url':"
1331
1335
  echo " --format FMT Output format: text (default) or json"
@@ -1333,10 +1337,13 @@ cmd_dashboard_help() {
1333
1337
  echo "Environment:"
1334
1338
  echo " LOKI_DASHBOARD_PORT Default port (overrides $DASHBOARD_DEFAULT_PORT)"
1335
1339
  echo " LOKI_DASHBOARD_HOST Default host (overrides $DASHBOARD_DEFAULT_HOST)"
1340
+ echo " LOKI_TLS_CERT Path to PEM certificate (enables HTTPS)"
1341
+ echo " LOKI_TLS_KEY Path to PEM private key (enables HTTPS)"
1336
1342
  echo ""
1337
1343
  echo "Examples:"
1338
1344
  echo " loki dashboard start # Start on default port"
1339
1345
  echo " loki dashboard start --port 8080 # Start on port 8080"
1346
+ echo " loki dashboard start --tls-cert cert.pem --tls-key key.pem"
1340
1347
  echo " loki dashboard status # Check if running"
1341
1348
  echo " loki dashboard url --format json # Get URL as JSON"
1342
1349
  echo " loki dashboard open # Open in browser"
@@ -1346,6 +1353,8 @@ cmd_dashboard_help() {
1346
1353
  cmd_dashboard_start() {
1347
1354
  local port="${LOKI_DASHBOARD_PORT:-$DASHBOARD_DEFAULT_PORT}"
1348
1355
  local host="${LOKI_DASHBOARD_HOST:-$DASHBOARD_DEFAULT_HOST}"
1356
+ local tls_cert="${LOKI_TLS_CERT:-}"
1357
+ local tls_key="${LOKI_TLS_KEY:-}"
1349
1358
 
1350
1359
  # Parse arguments
1351
1360
  while [[ $# -gt 0 ]]; do
@@ -1376,6 +1385,32 @@ cmd_dashboard_start() {
1376
1385
  host="${1#*=}"
1377
1386
  shift
1378
1387
  ;;
1388
+ --tls-cert)
1389
+ if [[ -n "${2:-}" ]]; then
1390
+ tls_cert="$2"
1391
+ shift 2
1392
+ else
1393
+ echo -e "${RED}--tls-cert requires a path${NC}"
1394
+ exit 1
1395
+ fi
1396
+ ;;
1397
+ --tls-cert=*)
1398
+ tls_cert="${1#*=}"
1399
+ shift
1400
+ ;;
1401
+ --tls-key)
1402
+ if [[ -n "${2:-}" ]]; then
1403
+ tls_key="$2"
1404
+ shift 2
1405
+ else
1406
+ echo -e "${RED}--tls-key requires a path${NC}"
1407
+ exit 1
1408
+ fi
1409
+ ;;
1410
+ --tls-key=*)
1411
+ tls_key="${1#*=}"
1412
+ shift
1413
+ ;;
1379
1414
  --help|-h)
1380
1415
  cmd_dashboard_help
1381
1416
  exit 0
@@ -1445,14 +1480,27 @@ cmd_dashboard_start() {
1445
1480
  mkdir -p "$log_dir"
1446
1481
  local log_file="${log_dir}/dashboard.log"
1447
1482
 
1483
+ # Determine URL scheme based on TLS
1484
+ local url_scheme="http"
1485
+ local tls_info=""
1486
+ if [ -n "$tls_cert" ] && [ -n "$tls_key" ]; then
1487
+ url_scheme="https"
1488
+ tls_info=" (TLS enabled)"
1489
+ fi
1490
+
1448
1491
  echo -e "${GREEN}Starting dashboard server...${NC}"
1449
1492
  echo -e "${CYAN}Host:${NC} $host"
1450
1493
  echo -e "${CYAN}Port:${NC} $port"
1494
+ if [ -n "$tls_info" ]; then
1495
+ echo -e "${CYAN}TLS:${NC} enabled"
1496
+ fi
1451
1497
  echo ""
1452
1498
 
1453
1499
  # Start the dashboard server in background
1454
1500
  # LOKI_SKILL_DIR tells server.py where to find static files
1455
- LOKI_DIR="$LOKI_DIR" LOKI_SKILL_DIR="$SKILL_DIR" PYTHONPATH="$SKILL_DIR" LOKI_DASHBOARD_HOST="$host" LOKI_DASHBOARD_PORT="$port" \
1501
+ LOKI_DIR="$LOKI_DIR" LOKI_SKILL_DIR="$SKILL_DIR" PYTHONPATH="$SKILL_DIR" \
1502
+ LOKI_DASHBOARD_HOST="$host" LOKI_DASHBOARD_PORT="$port" \
1503
+ LOKI_TLS_CERT="$tls_cert" LOKI_TLS_KEY="$tls_key" \
1456
1504
  nohup "$python_cmd" -m dashboard.server > "$log_file" 2>&1 &
1457
1505
  local new_pid=$!
1458
1506
 
@@ -1462,12 +1510,13 @@ cmd_dashboard_start() {
1462
1510
  # Also save port and host for status command
1463
1511
  echo "$port" > "${DASHBOARD_PID_DIR}/port"
1464
1512
  echo "$host" > "${DASHBOARD_PID_DIR}/host"
1513
+ echo "$url_scheme" > "${DASHBOARD_PID_DIR}/scheme"
1465
1514
 
1466
1515
  # Wait a moment and check if process is still running
1467
1516
  sleep 1
1468
1517
 
1469
1518
  if kill -0 "$new_pid" 2>/dev/null; then
1470
- local url="http://${host}:${port}"
1519
+ local url="${url_scheme}://${host}:${port}"
1471
1520
  echo -e "${GREEN}Dashboard server started${NC}"
1472
1521
  echo ""
1473
1522
  echo " PID: $new_pid"
@@ -1549,9 +1598,10 @@ cmd_dashboard_status() {
1549
1598
  fi
1550
1599
 
1551
1600
  if kill -0 "$pid" 2>/dev/null; then
1552
- # Read saved host and port
1601
+ # Read saved host, port, and scheme
1553
1602
  local host="${DASHBOARD_DEFAULT_HOST}"
1554
1603
  local port="${DASHBOARD_DEFAULT_PORT}"
1604
+ local scheme="http"
1555
1605
 
1556
1606
  if [ -f "${DASHBOARD_PID_DIR}/host" ]; then
1557
1607
  host=$(cat "${DASHBOARD_PID_DIR}/host" 2>/dev/null)
@@ -1559,20 +1609,30 @@ cmd_dashboard_status() {
1559
1609
  if [ -f "${DASHBOARD_PID_DIR}/port" ]; then
1560
1610
  port=$(cat "${DASHBOARD_PID_DIR}/port" 2>/dev/null)
1561
1611
  fi
1612
+ if [ -f "${DASHBOARD_PID_DIR}/scheme" ]; then
1613
+ scheme=$(cat "${DASHBOARD_PID_DIR}/scheme" 2>/dev/null)
1614
+ fi
1562
1615
 
1563
- local url="http://${host}:${port}"
1616
+ local url="${scheme}://${host}:${port}"
1564
1617
 
1565
1618
  echo -e "${GREEN}Status: Running${NC}"
1566
1619
  echo ""
1567
1620
  echo " PID: $pid"
1568
1621
  echo " Host: $host"
1569
1622
  echo " Port: $port"
1623
+ if [ "$scheme" = "https" ]; then
1624
+ echo " TLS: enabled"
1625
+ fi
1570
1626
  echo " URL: $url"
1571
1627
  echo ""
1572
1628
 
1573
1629
  # Check if server is responding
1630
+ local curl_flags="-s --connect-timeout 2"
1631
+ if [ "$scheme" = "https" ]; then
1632
+ curl_flags="$curl_flags -k"
1633
+ fi
1574
1634
  if command -v curl &> /dev/null; then
1575
- if curl -s --connect-timeout 2 "$url" &> /dev/null; then
1635
+ if curl $curl_flags "$url" &> /dev/null; then
1576
1636
  echo -e "${GREEN}Server is responding${NC}"
1577
1637
  else
1578
1638
  echo -e "${YELLOW}Server process running but not responding on $url${NC}"
@@ -1653,9 +1713,10 @@ cmd_dashboard_url() {
1653
1713
  exit 1
1654
1714
  fi
1655
1715
 
1656
- # Read saved host and port
1716
+ # Read saved host, port, and scheme
1657
1717
  local host="${DASHBOARD_DEFAULT_HOST}"
1658
1718
  local port="${DASHBOARD_DEFAULT_PORT}"
1719
+ local scheme="http"
1659
1720
 
1660
1721
  if [ -f "${DASHBOARD_PID_DIR}/host" ]; then
1661
1722
  host=$(cat "${DASHBOARD_PID_DIR}/host" 2>/dev/null)
@@ -1663,11 +1724,14 @@ cmd_dashboard_url() {
1663
1724
  if [ -f "${DASHBOARD_PID_DIR}/port" ]; then
1664
1725
  port=$(cat "${DASHBOARD_PID_DIR}/port" 2>/dev/null)
1665
1726
  fi
1727
+ if [ -f "${DASHBOARD_PID_DIR}/scheme" ]; then
1728
+ scheme=$(cat "${DASHBOARD_PID_DIR}/scheme" 2>/dev/null)
1729
+ fi
1666
1730
 
1667
- local url="http://${host}:${port}"
1731
+ local url="${scheme}://${host}:${port}"
1668
1732
 
1669
1733
  if [[ "$format" == "json" ]]; then
1670
- echo "{\"running\":true,\"url\":\"$url\",\"host\":\"$host\",\"port\":$port,\"pid\":$pid}"
1734
+ echo "{\"running\":true,\"url\":\"$url\",\"scheme\":\"$scheme\",\"host\":\"$host\",\"port\":$port,\"pid\":$pid}"
1671
1735
  else
1672
1736
  echo "$url"
1673
1737
  fi
@@ -1693,9 +1757,10 @@ cmd_dashboard_open() {
1693
1757
  exit 1
1694
1758
  fi
1695
1759
 
1696
- # Read saved host and port
1760
+ # Read saved host, port, and scheme
1697
1761
  local host="${DASHBOARD_DEFAULT_HOST}"
1698
1762
  local port="${DASHBOARD_DEFAULT_PORT}"
1763
+ local scheme="http"
1699
1764
 
1700
1765
  if [ -f "${DASHBOARD_PID_DIR}/host" ]; then
1701
1766
  host=$(cat "${DASHBOARD_PID_DIR}/host" 2>/dev/null)
@@ -1703,8 +1768,11 @@ cmd_dashboard_open() {
1703
1768
  if [ -f "${DASHBOARD_PID_DIR}/port" ]; then
1704
1769
  port=$(cat "${DASHBOARD_PID_DIR}/port" 2>/dev/null)
1705
1770
  fi
1771
+ if [ -f "${DASHBOARD_PID_DIR}/scheme" ]; then
1772
+ scheme=$(cat "${DASHBOARD_PID_DIR}/scheme" 2>/dev/null)
1773
+ fi
1706
1774
 
1707
- local url="http://${host}:${port}"
1775
+ local url="${scheme}://${host}:${port}"
1708
1776
 
1709
1777
  echo -e "${GREEN}Opening dashboard: $url${NC}"
1710
1778
 
@@ -2747,6 +2815,78 @@ cmd_version() {
2747
2815
  echo "Loki Mode v$(get_version)"
2748
2816
  }
2749
2817
 
2818
+ # Secrets / credential management
2819
+ cmd_secrets() {
2820
+ case "${1:-status}" in
2821
+ status)
2822
+ echo "API Key Status:"
2823
+ echo ""
2824
+ for key_var in ANTHROPIC_API_KEY OPENAI_API_KEY GOOGLE_API_KEY; do
2825
+ local value="${!key_var:-}"
2826
+ if [[ -n "$value" ]]; then
2827
+ local masked="${value:0:8}...${value: -4}"
2828
+ echo " $key_var: SET ($masked, ${#value} chars)"
2829
+ else
2830
+ # Check secret file mounts
2831
+ local lower_name
2832
+ lower_name=$(echo "$key_var" | tr '[:upper:]' '[:lower:]')
2833
+ local found=false
2834
+ for mount_path in /run/secrets /var/run/secrets; do
2835
+ if [[ -f "$mount_path/$lower_name" ]]; then
2836
+ echo " $key_var: AVAILABLE (secret file: $mount_path/$lower_name)"
2837
+ found=true
2838
+ break
2839
+ fi
2840
+ done
2841
+ if [[ "$found" != "true" ]]; then
2842
+ echo " $key_var: NOT SET"
2843
+ fi
2844
+ fi
2845
+ done
2846
+ ;;
2847
+ validate)
2848
+ echo "Validating API keys..."
2849
+ python3 -c "
2850
+ import sys
2851
+ sys.path.insert(0, '$(dirname "$(dirname "$(resolve_script_path "$0")")")')
2852
+ from dashboard.secrets import load_secrets
2853
+ result = load_secrets()
2854
+ for name, info in result.items():
2855
+ status = 'OK' if info['valid_format'] else 'INVALID'
2856
+ source = info['source']
2857
+ masked = info['masked']
2858
+ warning = info.get('warning', '')
2859
+ if info['set']:
2860
+ print(f' {name}: {status} ({masked}, source: {source})')
2861
+ if warning:
2862
+ print(f' WARNING: {warning}')
2863
+ else:
2864
+ print(f' {name}: NOT SET')
2865
+ " 2>/dev/null || echo " (Python validation unavailable, showing basic status)"
2866
+ ;;
2867
+ help)
2868
+ echo "Usage: loki secrets [status|validate|help]"
2869
+ echo ""
2870
+ echo "Manage API keys and credentials."
2871
+ echo ""
2872
+ echo "Commands:"
2873
+ echo " status Show which API keys are configured (default)"
2874
+ echo " validate Validate API key formats"
2875
+ echo " help Show this help"
2876
+ echo ""
2877
+ echo "Secret Loading Priority:"
2878
+ echo " 1. Environment variable (ANTHROPIC_API_KEY, etc.)"
2879
+ echo " 2. Docker/K8s secret file (/run/secrets/anthropic_api_key)"
2880
+ echo " 3. Not set"
2881
+ ;;
2882
+ *)
2883
+ echo "Unknown secrets command: $1"
2884
+ cmd_secrets help
2885
+ return 1
2886
+ ;;
2887
+ esac
2888
+ }
2889
+
2750
2890
  # Show recent logs
2751
2891
  cmd_logs() {
2752
2892
  local lines="${1:-50}"
@@ -2788,7 +2928,11 @@ cmd_api() {
2788
2928
 
2789
2929
  # Start server
2790
2930
  mkdir -p "$LOKI_DIR/logs" "$LOKI_DIR/dashboard"
2791
- LOKI_DIR="$LOKI_DIR" nohup python3 -m uvicorn dashboard.server:app --host 0.0.0.0 --port "$port" > "$LOKI_DIR/logs/api.log" 2>&1 &
2931
+ local uvicorn_args="--host 0.0.0.0 --port $port"
2932
+ if [ -n "${LOKI_TLS_CERT:-}" ] && [ -n "${LOKI_TLS_KEY:-}" ]; then
2933
+ uvicorn_args="$uvicorn_args --ssl-certfile ${LOKI_TLS_CERT} --ssl-keyfile ${LOKI_TLS_KEY}"
2934
+ fi
2935
+ LOKI_DIR="$LOKI_DIR" nohup python3 -m uvicorn dashboard.server:app $uvicorn_args > "$LOKI_DIR/logs/api.log" 2>&1 &
2792
2936
  local new_pid=$!
2793
2937
  echo "$new_pid" > "$pid_file"
2794
2938
 
@@ -3957,6 +4101,113 @@ _list_templates() {
3957
4101
  echo "Usage: loki init --template <name>"
3958
4102
  }
3959
4103
 
4104
+ # Watchdog: process health monitoring
4105
+ cmd_watchdog() {
4106
+ local subcommand="${1:-status}"
4107
+ shift 2>/dev/null || true
4108
+
4109
+ case "$subcommand" in
4110
+ status)
4111
+ # Show watchdog state
4112
+ if [[ "${LOKI_WATCHDOG:-false}" == "true" ]]; then
4113
+ echo -e "${GREEN}Watchdog: ENABLED${NC} (interval: ${LOKI_WATCHDOG_INTERVAL:-30}s)"
4114
+ else
4115
+ echo "Watchdog: DISABLED"
4116
+ echo "Enable with: LOKI_WATCHDOG=true loki start"
4117
+ fi
4118
+
4119
+ echo ""
4120
+ echo -e "${BOLD}Process Health:${NC}"
4121
+
4122
+ # Check dashboard
4123
+ local dpid_file="$LOKI_DIR/dashboard/dashboard.pid"
4124
+ if [[ -f "$dpid_file" ]]; then
4125
+ local dpid
4126
+ dpid=$(cat "$dpid_file" 2>/dev/null)
4127
+ if [[ -n "$dpid" ]] && kill -0 "$dpid" 2>/dev/null; then
4128
+ echo -e " Dashboard (PID $dpid): ${GREEN}alive${NC}"
4129
+ else
4130
+ echo -e " Dashboard (PID ${dpid:-?}): ${RED}DEAD${NC}"
4131
+ fi
4132
+ else
4133
+ echo -e " Dashboard: ${DIM}not running${NC}"
4134
+ fi
4135
+
4136
+ # Check session
4137
+ local spid_file="$LOKI_DIR/loki.pid"
4138
+ if [[ -f "$spid_file" ]]; then
4139
+ local spid
4140
+ spid=$(cat "$spid_file" 2>/dev/null)
4141
+ if [[ -n "$spid" ]] && kill -0 "$spid" 2>/dev/null; then
4142
+ echo -e " Session (PID $spid): ${GREEN}alive${NC}"
4143
+ else
4144
+ echo -e " Session (PID ${spid:-?}): ${RED}DEAD${NC}"
4145
+ fi
4146
+ else
4147
+ echo -e " Session: ${DIM}not running${NC}"
4148
+ fi
4149
+
4150
+ # Check agents
4151
+ local agents_file="$LOKI_DIR/state/agents.json"
4152
+ if [[ -f "$agents_file" ]]; then
4153
+ local agent_info
4154
+ agent_info=$(python3 -c "
4155
+ import json, os
4156
+ try:
4157
+ agents = json.load(open('$agents_file'))
4158
+ alive = dead = other = 0
4159
+ for a in agents:
4160
+ pid = a.get('pid')
4161
+ status = a.get('status', '')
4162
+ if status in ('terminated', 'completed', 'failed', 'crashed'):
4163
+ other += 1
4164
+ continue
4165
+ if pid:
4166
+ try:
4167
+ os.kill(int(pid), 0)
4168
+ alive += 1
4169
+ except (OSError, ValueError):
4170
+ dead += 1
4171
+ else:
4172
+ other += 1
4173
+ print(f'{alive}:{dead}:{other}')
4174
+ except Exception:
4175
+ print('0:0:0')
4176
+ " 2>/dev/null || echo "0:0:0")
4177
+ local a_alive a_dead a_other
4178
+ IFS=: read -r a_alive a_dead a_other <<< "$agent_info"
4179
+ if [[ "$a_alive" -gt 0 ]] || [[ "$a_dead" -gt 0 ]]; then
4180
+ echo -e " Agents: ${GREEN}${a_alive} alive${NC}, ${RED}${a_dead} dead${NC}, ${DIM}${a_other} finished${NC}"
4181
+ elif [[ "$a_other" -gt 0 ]]; then
4182
+ echo -e " Agents: ${DIM}${a_other} finished${NC}"
4183
+ else
4184
+ echo -e " Agents: ${DIM}none${NC}"
4185
+ fi
4186
+ else
4187
+ echo -e " Agents: ${DIM}none${NC}"
4188
+ fi
4189
+ ;;
4190
+ help)
4191
+ echo "Usage: loki watchdog [status|help]"
4192
+ echo ""
4193
+ echo "Monitor process health for Loki Mode sessions."
4194
+ echo ""
4195
+ echo "Subcommands:"
4196
+ echo " status Show health of dashboard, session, and agent processes (default)"
4197
+ echo " help Show this help"
4198
+ echo ""
4199
+ echo "Environment:"
4200
+ echo " LOKI_WATCHDOG=true Enable watchdog monitoring during sessions"
4201
+ echo " LOKI_WATCHDOG_INTERVAL=30 Check interval in seconds (default: 30)"
4202
+ ;;
4203
+ *)
4204
+ echo -e "${RED}Unknown watchdog command: $subcommand${NC}"
4205
+ cmd_watchdog help
4206
+ return 1
4207
+ ;;
4208
+ esac
4209
+ }
4210
+
3960
4211
  # Main command dispatcher
3961
4212
  main() {
3962
4213
  if [ $# -eq 0 ]; then
@@ -4049,9 +4300,15 @@ main() {
4049
4300
  voice)
4050
4301
  cmd_voice "$@"
4051
4302
  ;;
4303
+ secrets)
4304
+ cmd_secrets "$@"
4305
+ ;;
4052
4306
  doctor)
4053
4307
  cmd_doctor "$@"
4054
4308
  ;;
4309
+ watchdog)
4310
+ cmd_watchdog "$@"
4311
+ ;;
4055
4312
  version|--version|-v)
4056
4313
  cmd_version
4057
4314
  ;;
@@ -6251,24 +6508,43 @@ cmd_enterprise() {
6251
6508
  echo ""
6252
6509
 
6253
6510
  local auth_enabled="${LOKI_ENTERPRISE_AUTH:-false}"
6254
- local audit_enabled="${LOKI_ENTERPRISE_AUDIT:-false}"
6511
+ local audit_disabled="${LOKI_AUDIT_DISABLED:-false}"
6512
+ local audit_force_on="${LOKI_ENTERPRISE_AUDIT:-false}"
6255
6513
 
6256
6514
  if [ "$auth_enabled" = "true" ] || [ "$auth_enabled" = "1" ]; then
6257
- echo -e " Authentication: ${GREEN}Enabled${NC}"
6515
+ echo -e " Token Auth: ${GREEN}Enabled${NC}"
6258
6516
  else
6259
- echo -e " Authentication: ${DIM}Disabled${NC}"
6517
+ echo -e " Token Auth: ${DIM}Disabled${NC}"
6260
6518
  fi
6261
6519
 
6262
- if [ "$audit_enabled" = "true" ] || [ "$audit_enabled" = "1" ]; then
6263
- echo -e " Audit Logging: ${GREEN}Enabled${NC}"
6520
+ # OIDC/SSO status
6521
+ local oidc_issuer="${LOKI_OIDC_ISSUER:-}"
6522
+ local oidc_client="${LOKI_OIDC_CLIENT_ID:-}"
6523
+ if [ -n "$oidc_issuer" ] && [ -n "$oidc_client" ]; then
6524
+ echo -e " OIDC/SSO: ${GREEN}Enabled${NC} (${oidc_issuer})"
6264
6525
  else
6526
+ echo -e " OIDC/SSO: ${DIM}Disabled${NC}"
6527
+ fi
6528
+
6529
+ # Audit is on by default; disabled only if LOKI_AUDIT_DISABLED=true
6530
+ if [ "$audit_force_on" = "true" ] || [ "$audit_force_on" = "1" ]; then
6531
+ echo -e " Audit Logging: ${GREEN}Enabled (enterprise)${NC}"
6532
+ elif [ "$audit_disabled" = "true" ] || [ "$audit_disabled" = "1" ]; then
6265
6533
  echo -e " Audit Logging: ${DIM}Disabled${NC}"
6534
+ else
6535
+ echo -e " Audit Logging: ${GREEN}Enabled (default)${NC}"
6266
6536
  fi
6267
6537
 
6268
6538
  echo ""
6269
- echo "Enable with environment variables:"
6270
- echo " export LOKI_ENTERPRISE_AUTH=true"
6271
- echo " export LOKI_ENTERPRISE_AUDIT=true"
6539
+ echo "Configure with environment variables:"
6540
+ echo " export LOKI_ENTERPRISE_AUTH=true # Token authentication"
6541
+ echo " export LOKI_AUDIT_DISABLED=true # Disable audit logging"
6542
+ echo " export LOKI_ENTERPRISE_AUDIT=true # Force audit on (legacy)"
6543
+ echo ""
6544
+ echo "OIDC/SSO (optional, works alongside token auth):"
6545
+ echo " export LOKI_OIDC_ISSUER=https://accounts.google.com"
6546
+ echo " export LOKI_OIDC_CLIENT_ID=your-client-id"
6547
+ echo " export LOKI_OIDC_AUDIENCE=your-audience # Optional, defaults to client_id"
6272
6548
  ;;
6273
6549
 
6274
6550
  token)
@@ -6547,10 +6823,15 @@ else:
6547
6823
  audit)
6548
6824
  local audit_cmd="${2:-summary}"
6549
6825
 
6550
- if [ "${LOKI_ENTERPRISE_AUDIT:-}" != "true" ] && [ "${LOKI_ENTERPRISE_AUDIT:-}" != "1" ]; then
6551
- echo -e "${YELLOW}Audit logging is not enabled${NC}"
6552
- echo "Enable with: export LOKI_ENTERPRISE_AUDIT=true"
6553
- exit 1
6826
+ # Audit is on by default. Only blocked if explicitly disabled and not force-enabled.
6827
+ local _audit_disabled="${LOKI_AUDIT_DISABLED:-false}"
6828
+ local _audit_force="${LOKI_ENTERPRISE_AUDIT:-false}"
6829
+ if [ "$_audit_force" != "true" ] && [ "$_audit_force" != "1" ]; then
6830
+ if [ "$_audit_disabled" = "true" ] || [ "$_audit_disabled" = "1" ]; then
6831
+ echo -e "${YELLOW}Audit logging is disabled${NC}"
6832
+ echo "Remove LOKI_AUDIT_DISABLED or set LOKI_ENTERPRISE_AUDIT=true"
6833
+ exit 1
6834
+ fi
6554
6835
  fi
6555
6836
 
6556
6837
  local audit_dir="${HOME}/.loki/dashboard/audit"
@@ -6658,13 +6939,19 @@ for line in sys.stdin:
6658
6939
  echo "Commands:"
6659
6940
  echo " status Show which enterprise features are enabled"
6660
6941
  echo " token <cmd> Manage API tokens (requires LOKI_ENTERPRISE_AUTH=true)"
6661
- echo " audit <cmd> Query audit logs (requires LOKI_ENTERPRISE_AUDIT=true)"
6942
+ echo " audit <cmd> Query audit logs (enabled by default)"
6943
+ echo ""
6944
+ echo "Configure enterprise features:"
6945
+ echo " export LOKI_ENTERPRISE_AUTH=true # Token authentication"
6946
+ echo " export LOKI_AUDIT_DISABLED=true # Disable audit logging"
6947
+ echo " export LOKI_ENTERPRISE_AUDIT=true # Force audit on (legacy)"
6662
6948
  echo ""
6663
- echo "Enable enterprise features:"
6664
- echo " export LOKI_ENTERPRISE_AUTH=true # Token authentication"
6665
- echo " export LOKI_ENTERPRISE_AUDIT=true # Audit logging"
6949
+ echo "OIDC/SSO (optional, works alongside token auth):"
6950
+ echo " export LOKI_OIDC_ISSUER=https://accounts.google.com"
6951
+ echo " export LOKI_OIDC_CLIENT_ID=your-client-id"
6952
+ echo " export LOKI_OIDC_AUDIENCE=your-audience # Optional"
6666
6953
  echo ""
6667
- echo "These features are optional and NOT required for community use."
6954
+ echo "Audit logging is enabled by default. Auth is optional."
6668
6955
  ;;
6669
6956
 
6670
6957
  *)