============================================================ SHiRE MOBILE SENTINEL GATEWAY INSPECTION REPORT ============================================================ Generated: 2026-08-05T10:58:19+08:00 Hostname: Work Mobile project: /home/ray/ARMOR/apps/shire-mobile ARMOR: /home/shire3d/ARMOR SHiREVault: /mnt/shirevault-network //192.168.1.1/volume(sda2) cifs === LIVE MOBILE GATEWAY PROCESS === Port: 8795 PID: 1154041 Executable: /usr/bin/python3.12 Working directory: / Source script: /usr/local/lib/shire-mobile-gateway/server.py PID PPID USER GROUP COMMAND ELAPSED %CPU %MEM 1154041 1 ray ray python 2-16:11:07 0.0 0.1 Redacted command line: /home/shire3d/ARMOR/venv/bin/python /usr/local/lib/shire-mobile-gateway/server.py === PROCESS SYSTEMD OWNERSHIP === * shire-mobile-gateway.service - SHiRE Mobile Private Command Gateway Loaded: loaded (/etc/systemd/system/shire-mobile-gateway.service; enabled; preset: enabled) Active: active (running) since Sun 2026-08-02 18:47:11 AWST; 2 days ago Main PID: 1154041 (python) Tasks: 1 (limit: 16648) Memory: 12.7M (peak: 14.8M swap: 144.0K swap peak: 144.0K) CPU: 26.509s CGroup: /system.slice/shire-mobile-gateway.service `-1154041 /home/shire3d/ARMOR/venv/bin/python /usr/local/lib/shire-mobile-gateway/server.py Aug 03 04:07:27 Work python[1154041]: {"timestamp": "2026-08-02T20:07:27.038677+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 04:26:43 Work python[1154041]: {"timestamp": "2026-08-02T20:26:43.197672+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 04:38:13 Work python[1154041]: {"timestamp": "2026-08-02T20:38:13.976594+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 04:54:02 Work python[1154041]: {"timestamp": "2026-08-02T20:54:02.770388+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 05:07:34 Work python[1154041]: {"timestamp": "2026-08-02T21:07:34.239647+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 05:22:59 Work python[1154041]: {"timestamp": "2026-08-02T21:22:59.346109+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 05:38:35 Work python[1154041]: {"timestamp": "2026-08-02T21:38:35.756632+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 05:52:41 Work python[1154041]: {"timestamp": "2026-08-02T21:52:41.259616+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 07:03:31 Work python[1154041]: {"timestamp": "2026-08-02T23:03:31.444332+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Aug 03 07:45:41 Work python[1154041]: {"timestamp": "2026-08-02T23:45:41.816836+00:00", "client": "100.110.126.100", "message": "\"GET /v1/sentinel/status HTTP/1.1\" 200 -"} Detected unit: shire-mobile-gateway.service ExecStart={ path=/home/shire3d/ARMOR/venv/bin/python ; argv[]=/home/shire3d/ARMOR/venv/bin/python /usr/local/lib/shire-mobile-gateway/server.py ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 } EnvironmentFiles=/etc/shire-mobile-gateway/mobile-gateway.env (ignore_errors=no) WorkingDirectory= User=ray Group=ray FragmentPath=/etc/systemd/system/shire-mobile-gateway.service === GATEWAY SOURCE IDENTITY === FILE: /usr/local/lib/shire-mobile-gateway/server.py OWNER: root:root MODE: -rwxr-xr-x (755) SIZE: 18252 bytes MODIFIED: 2026-08-02 18:47:11.585687796 +0800 efbae99a479d5d258c5f6e62d57de29ac326bed18acb62c9d61cde4202aacd33 /usr/local/lib/shire-mobile-gateway/server.py === GATEWAY SENTINEL AND AUTHENTICATION SECTIONS === ----- lines 1-98 ----- 1: #!/usr/bin/env python3 2: from __future__ import annotations 3: 4: import json 5: import os 6: import re 7: import subprocess 8: import time 9: import urllib.error 10: import urllib.request 11: from datetime import datetime, timezone 12: from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer 13: from pathlib import Path 14: from typing import Any 15: 16: HOST = os.environ.get("SHIRE_MOBILE_GATEWAY_HOST", "127.0.0.1") 17: PORT = int(os.environ.get("SHIRE_MOBILE_GATEWAY_PORT", "8795")) 18: TOKEN = os.environ.get("SHIRE_MOBILE_GATEWAY_TOKEN", "") 19: OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://127.0.0.1:11434").rstrip("/") 20: FAST_MODEL = os.environ.get("SHIRE_FAST_MODEL", "shire-mini-fast:qwen3.5-4b") 21: DEEP_MODEL = os.environ.get("SHIRE_DEEP_MODEL", "shire-mini-deep:qwen3.5-9b") 22: 23: SENTINEL_DATA = Path("/home/shire3d/ARMOR/data/sentinel") 24: ACTION_ROOT = Path("/home/ray/.local/share/shire-mobile-gateway") 25: ACTION_LOG = ACTION_ROOT / "sentinel-actions.jsonl" 26: 27: MAX_BODY = 256 * 1024 28: MAX_MESSAGE = 8000 29: MAX_HISTORY = 30 30: ALLOWED_ACTIONS = { 31: "acknowledge", 32: "request_investigation", 33: "mark_false_positive", 34: "defer", 35: } 36: 37: # SHIRE_MOBILE_CHAT_SPEED_0701 38: SYSTEM_STATUS_UNITS = { 39: "SHiRE Brain": "shire-brain.service", 40: "Mobile Gateway": "shire-mobile-gateway.service", 41: "Approval Hub": "shire-approval-hub.service", 42: "Sentinel Alert Bridge": "shire-sentinel-alert.service", 43: "Sentinel Suricata IDS": "shire-sentinel-suricata.service", 44: "Academy UI": "shire-academy-ui.service", 45: "Academy CadQuery Engine": "shire-academy-cadquery-fast.service", 46: "Specialist Agent Hub": "shire-agent-hub.service", 47: "Unified Learning": "shire-unified-learning.service", 48: "Marketing Boss": "shire-marketing-boss.service", 49: "TrendScout": "shire-trendscout.service", 50: } 51: 52: SYSTEM_STATUS_PHRASES = ( 53: "systems are online", 54: "systems online", 55: "what is online", 56: "what's online", 57: "which systems are online", 58: "system status", 59: "systems status", 60: "services online", 61: "services are online", 62: "what systems are running", 63: "what is running", 64: ) 65: 66: SYSTEM_PROMPT = """You are SHiRE, Ray's private local AI command companion running on SHiRE Mini. 67: Address Ray naturally as Chief when appropriate. Be warm, direct and practical. 68: You may explain, plan, analyse and help with defensive cyber-security on Ray's own 69: devices and networks. Never claim that a destructive, external, purchasing, 70: publishing, printing, firewall, router or Forge action happened unless an audited 71: approved tool reports that it happened. Keep Forge locked unless separately 72: approved. Do not provide offensive intrusion guidance. When uncertain, say so. 73: This mobile channel is private through Tailscale, but still avoid exposing secrets.""" 74: 75: SCAM_PROMPT = """You are SHiRE Scam Check, a defensive analyst. Analyse only the 76: provided message, URL, phone number, QR payload or description. Explain concrete 77: warning signs, what is unknown, the safest next steps, and a risk level from LOW, 78: MEDIUM, HIGH or CRITICAL. Do not claim to identify a real person or organisation 79: without evidence. Do not open links or perform external actions. Mention that this 80: is pattern analysis, not a live reputation lookup, unless live evidence is supplied.""" 81: 82: 83: def now_iso() -> str: 84: return datetime.now(timezone.utc).isoformat() 85: 86: 87: def run_command(command: list[str], timeout: int = 5) -> tuple[int, str]: 88: try: 89: completed = subprocess.run( 90: command, 91: text=True, 92: capture_output=True, 93: timeout=timeout, 94: check=False, 95: ) 96: output = (completed.stdout or completed.stderr or "").strip() 97: return completed.returncode, output 98: except Exception as exc: ----- lines 113-364 ----- 113: 114: def flatten_alerts(value: Any, source: str, found: list[dict[str, Any]]) -> None: 115: if len(found) >= 25: 116: return 117: 118: if isinstance(value, list): 119: for item in value[-25:]: 120: flatten_alerts(item, source, found) 121: return 122: 123: if not isinstance(value, dict): 124: return 125: 126: keys = {str(key).lower() for key in value} 127: looks_like_alert = bool( 128: keys 129: & { 130: "alert", 131: "signature", 132: "severity", 133: "event_type", 134: "threat", 135: "category", 136: "message", 137: "title", 138: } 139: ) 140: 141: if looks_like_alert: 142: alert = value.get("alert") 143: if isinstance(alert, dict): 144: title = ( 145: alert.get("signature") 146: or alert.get("category") 147: or value.get("message") 148: or "Sentinel alert" 149: ) 150: severity = alert.get("severity") or value.get("severity") or "unknown" 151: category = alert.get("category") or value.get("event_type") or "network" 152: else: 153: title = ( 154: value.get("signature") 155: or value.get("title") 156: or value.get("message") 157: or value.get("event_type") 158: or "Sentinel event" 159: ) 160: severity = value.get("severity") or value.get("priority") or "unknown" 161: category = value.get("category") or value.get("event_type") or "security" 162: 163: timestamp = ( 164: value.get("timestamp") 165: or value.get("updated_at") 166: or value.get("created_at") 167: or "" 168: ) 169: identifier = str( 170: value.get("id") 171: or value.get("event_id") 172: or f"{source}:{len(found) + 1}" 173: ) 174: 175: found.append( 176: { 177: "id": identifier[:160], 178: "title": str(title)[:500], 179: "severity": str(severity)[:80], 180: "category": str(category)[:160], 181: "timestamp": str(timestamp)[:160], 182: "source": source, 183: } 184: ) 185: 186: for child in value.values(): 187: if isinstance(child, (dict, list)): 188: flatten_alerts(child, source, found) 189: 190: 191: def recent_sentinel_alerts() -> list[dict[str, Any]]: 192: found: list[dict[str, Any]] = [] 193: if not SENTINEL_DATA.exists(): 194: return found 195: 196: paths = sorted( 197: [ 198: path 199: for path in SENTINEL_DATA.rglob("*") 200: if path.is_file() and path.suffix.lower() in {".json", ".jsonl"} 201: ], 202: key=lambda path: path.stat().st_mtime, 203: reverse=True, 204: )[:30] 205: 206: for path in paths: 207: if len(found) >= 25: 208: break 209: try: 210: if path.suffix.lower() == ".jsonl": 211: lines = path.read_text( 212: encoding="utf-8", 213: errors="replace", 214: ).splitlines()[-40:] 215: for line in lines: 216: try: 217: flatten_alerts(json.loads(line), path.name, found) 218: except Exception: 219: continue 220: else: 221: flatten_alerts(json_from_file(path), path.name, found) 222: except Exception: 223: continue 224: 225: return found[-20:][::-1] 226: 227: 228: def listener_summary() -> list[str]: 229: code, output = run_command(["ss", "-lntH"], timeout=5) 230: if code != 0: 231: return [] 232: 233: listeners: list[str] = [] 234: for line in output.splitlines(): 235: fields = line.split() 236: if len(fields) < 4: 237: continue 238: address = fields[3] 239: if address.startswith("127.") or address.startswith("[::1]"): 240: continue 241: listeners.append(address) 242: return sorted(set(listeners))[:30] 243: 244: 245: def sentinel_status() -> dict[str, Any]: 246: bridge_path = SENTINEL_DATA / "alert_bridge_status.json" 247: bridge = json_from_file(bridge_path) 248: 249: return { 250: "ok": True, 251: "generated_at": now_iso(), 252: "boundary": "observe, report and approval-gated response only", 253: "services": { 254: "sentinel_alert": service_state("shire-sentinel-alert.service"), 255: "sentinel_suricata": service_state("shire-sentinel-suricata.service"), 256: "tailscale": service_state("tailscaled.service"), 257: "brain": service_state("shire-brain.service"), 258: "approval_hub": service_state("shire-approval-hub.service"), 259: }, 260: "alert_bridge": bridge if isinstance(bridge, dict) else {}, 261: "recent_alerts": recent_sentinel_alerts(), 262: "non_loopback_listeners": listener_summary(), 263: "supported_actions": sorted(ALLOWED_ACTIONS), 264: "blocked_actions": [ 265: "automatic isolation", 266: "automatic router blocking", 267: "offensive scanning", 268: "credential attacks", 269: ], 270: } 271: 272: 273: 274: def is_direct_system_status_question(message: str) -> bool: 275: normalised = " ".join(message.lower().replace("’", "'").split()) 276: return any(phrase in normalised for phrase in SYSTEM_STATUS_PHRASES) 277: 278: 279: def direct_system_status_answer() -> str: 280: states = { 281: label: service_state(unit) 282: for label, unit in SYSTEM_STATUS_UNITS.items() 283: } 284: 285: online = [ 286: label 287: for label, state in states.items() 288: if state == "active" 289: ] 290: unavailable = [ 291: f"{label} ({state})" 292: for label, state in states.items() 293: if state != "active" 294: ] 295: 296: alerts = recent_sentinel_alerts() 297: lines = [ 298: "Here is the live SHiRE Mini status, Chief:", 299: "", 300: ] 301: lines.extend(f"• {label}: ONLINE" for label in online) 302: 303: if unavailable: 304: lines += ["", "Not currently active or unavailable:"] 305: lines.extend(f"• {item}" for item in unavailable) 306: 307: lines += [ 308: "", 309: f"Sentinel currently exposes {len(alerts)} structured recent event" 310: + ("" if len(alerts) == 1 else "s") 311: + " to the mobile feed.", 312: "No services or security controls were changed.", 313: ] 314: return "\n".join(lines) 315: 316: 317: def ollama_chat(messages: list[dict[str, str]], deep: bool = False) -> str: 318: model = DEEP_MODEL if deep else FAST_MODEL 319: payload = { 320: "model": model, 321: "messages": messages, 322: "stream": False, 323: "think": False, 324: "keep_alive": "10m", 325: "options": { 326: "temperature": 0.45, 327: "num_ctx": 3072, 328: "num_predict": 320, 329: }, 330: } 331: request = urllib.request.Request( 332: OLLAMA_URL + "/api/chat", 333: data=json.dumps(payload).encode("utf-8"), 334: headers={"Content-Type": "application/json"}, 335: method="POST", 336: ) 337: 338: try: 339: with urllib.request.urlopen(request, timeout=75) as response: 340: body = json.loads(response.read().decode("utf-8")) 341: except urllib.error.HTTPError as exc: 342: detail = exc.read().decode("utf-8", errors="replace") 343: raise RuntimeError(f"Local model HTTP {exc.code}: {detail[:500]}") from exc 344: except Exception as exc: 345: raise RuntimeError(f"Local SHiRE model unavailable: {exc}") from exc 346: 347: answer = str((body.get("message") or {}).get("content") or "").strip() 348: if not answer: 349: raise RuntimeError("Local SHiRE model returned an empty answer.") 350: return answer 351: 352: 353: def chat_response(payload: dict[str, Any]) -> dict[str, Any]: 354: message = str(payload.get("message") or "").strip() 355: if not message: 356: raise ValueError("message is required") 357: if len(message) > MAX_MESSAGE: 358: raise ValueError("message exceeds the 8000 character mobile limit") 359: 360: if is_direct_system_status_question(message): 361: return { 362: "ok": True, 363: "answer": direct_system_status_answer(), 364: "model_lane": "direct-live-status", ----- lines 380-558 ----- 380: messages.append({"role": "user", "content": message}) 381: answer = ollama_chat(messages, deep=bool(payload.get("deep"))) 382: return { 383: "ok": True, 384: "answer": answer, 385: "model_lane": "deep" if payload.get("deep") else "fast", 386: "generated_at": now_iso(), 387: } 388: 389: 390: def scam_response(payload: dict[str, Any]) -> dict[str, Any]: 391: content = str(payload.get("content") or "").strip() 392: if not content: 393: raise ValueError("content is required") 394: if len(content) > MAX_MESSAGE: 395: raise ValueError("content exceeds the 8000 character limit") 396: 397: answer = ollama_chat( 398: [ 399: {"role": "system", "content": SCAM_PROMPT}, 400: {"role": "user", "content": content}, 401: ], 402: deep=False, 403: ) 404: return { 405: "ok": True, 406: "analysis": answer, 407: "live_reputation_lookup": False, 408: "generated_at": now_iso(), 409: } 410: 411: 412: def record_action(payload: dict[str, Any]) -> dict[str, Any]: 413: action = str(payload.get("action") or "").strip() 414: if action not in ALLOWED_ACTIONS: 415: raise ValueError("unsupported or unsafe Sentinel action") 416: 417: record = { 418: "schema": "shire.mobile.sentinel.action.v1", 419: "timestamp": now_iso(), 420: "action": action, 421: "alert_id": str(payload.get("alert_id") or "")[:200], 422: "note": str(payload.get("note") or "")[:2000], 423: "effect": "audit only; no firewall, router or service state changed", 424: } 425: 426: ACTION_ROOT.mkdir(parents=True, exist_ok=True) 427: with ACTION_LOG.open("a", encoding="utf-8") as handle: 428: handle.write(json.dumps(record, sort_keys=True) + "\n") 429: 430: return {"ok": True, "record": record} 431: 432: 433: class Handler(BaseHTTPRequestHandler): 434: server_version = "SHiREMobileGateway/0.7.0" 435: 436: def log_message(self, fmt: str, *args: Any) -> None: 437: print( 438: json.dumps( 439: { 440: "timestamp": now_iso(), 441: "client": self.client_address[0], 442: "message": fmt % args, 443: } 444: ), 445: flush=True, 446: ) 447: 448: def _authorised(self) -> bool: 449: supplied = self.headers.get("Authorization", "") 450: return bool(TOKEN) and supplied == f"Bearer {TOKEN}" 451: 452: def _send(self, status: int, payload: dict[str, Any]) -> None: 453: body = json.dumps(payload, ensure_ascii=False).encode("utf-8") 454: self.send_response(status) 455: self.send_header("Content-Type", "application/json; charset=utf-8") 456: self.send_header("Cache-Control", "no-store") 457: self.send_header("Content-Length", str(len(body))) 458: self.end_headers() 459: self.wfile.write(body) 460: 461: def _read_json(self) -> dict[str, Any]: 462: length = int(self.headers.get("Content-Length", "0") or "0") 463: if length <= 0 or length > MAX_BODY: 464: raise ValueError("invalid request body length") 465: value = json.loads(self.rfile.read(length).decode("utf-8")) 466: if not isinstance(value, dict): 467: raise ValueError("JSON object required") 468: return value 469: 470: def do_GET(self) -> None: 471: if not self._authorised(): 472: self._send(401, {"ok": False, "error": "unauthorised"}) 473: return 474: 475: if self.path == "/v1/health": 476: self._send( 477: 200, 478: { 479: "ok": True, 480: "service": "shire-mobile-gateway", 481: "version": "0.7.0", 482: "private_binding": HOST, 483: "sentinel_mode": "read-only plus audited safe decisions", 484: "voice_model_ready": False, 485: "timestamp": now_iso(), 486: }, 487: ) 488: return 489: 490: if self.path == "/v1/sentinel/status": 491: self._send(200, sentinel_status()) 492: return 493: 494: if self.path == "/v1/voice/status": 495: self._send( 496: 200, 497: { 498: "ok": True, 499: "enrolment_capture_supported": True, 500: "ray_voice_model_ready": False, 501: "speech_to_text": "Pixel on-device recogniser", 502: "speech_output": "Android local TTS when enabled", 503: "audio_retention": "app-private enrolment samples only after consent", 504: }, 505: ) 506: return 507: 508: self._send(404, {"ok": False, "error": "not found"}) 509: 510: def do_POST(self) -> None: 511: if not self._authorised(): 512: self._send(401, {"ok": False, "error": "unauthorised"}) 513: return 514: 515: try: 516: payload = self._read_json() 517: 518: if self.path == "/v1/chat": 519: self._send(200, chat_response(payload)) 520: return 521: 522: if self.path == "/v1/scam-check": 523: self._send(200, scam_response(payload)) 524: return 525: 526: if self.path == "/v1/sentinel/action": 527: self._send(200, record_action(payload)) 528: return 529: 530: self._send(404, {"ok": False, "error": "not found"}) 531: except ValueError as exc: 532: self._send(400, {"ok": False, "error": str(exc)}) 533: except Exception as exc: 534: self._send(503, {"ok": False, "error": str(exc)}) 535: 536: 537: def main() -> None: 538: if not TOKEN: 539: raise SystemExit("SHIRE_MOBILE_GATEWAY_TOKEN is required") 540: ACTION_ROOT.mkdir(parents=True, exist_ok=True) 541: server = ThreadingHTTPServer((HOST, PORT), Handler) 542: print( 543: json.dumps( 544: { 545: "ok": True, 546: "service": "shire-mobile-gateway", 547: "host": HOST, 548: "port": PORT, 549: "started_at": now_iso(), 550: } 551: ), 552: flush=True, 553: ) 554: server.serve_forever() 555: 556: 557: if __name__ == "__main__": 558: main() === RELATED GATEWAY FILES === find: '/etc/audit': Permission denied find: '/etc/credstore.encrypted': Permission denied find: '/etc/credstore': Permission denied find: '/etc/shire-voice': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-limbforge-canvas-gateway.service-ODuNxv': Permission denied find: '/tmp/shire-marketing-pipeline-test-eE3i12': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-fwupd.service-V0KAJx': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-limbforge-workspace.service-3jSOWo': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-academy-cadquery-fast.service-kenFgC': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-academy-tailnet.service-gyKBga': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-systemd-resolved.service-sgksX1': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-scanforge-workspace.service-Ys0X8o': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-agent@covercanvas.service-UjEnDB': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-agent-hub-tailnet.service-ssaQMt': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-covercanvas-tailnet.service-R9DONN': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-systemd-timesyncd.service-A7PsQr': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-covercanvas-relief-engine.service-B3UpFA': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-sentinel-alert.service-4qgFR0': Permission denied find: '/tmp/shire-marketing-pipeline-test-YcraXH': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-covercanvas-workspace.service-rqitX7': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-marketing-boss.service-ZCQSfJ': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-sentinel-suricata.service-gwvXdF': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-trendscout.service-elnRwZ': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-marketing-pipeline.service-uMz9Zx': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-academy-ui.service-q7lWK4': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-approval-hub.service-ruMf5x': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-limbforge-tailnet.service-ahfMfB': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-power-profiles-daemon.service-5Q5w8J': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-colord.service-D4fGiO': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-bluetooth.service-qffpxV': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-switcheroo-control.service-g5lu85': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-marketing-boss-tailnet.service-Prb947': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-marketing-cloudflare-tunnel.service-pzbLNq': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-upower.service-f2w9Fd': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-agent@scanforge.service-QF34nJ': Permission denied find: '/tmp/shire-marketing-pipeline-test-vldimZ': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-ModemManager.service-qPgCS9': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-agent-hub.service-po7903': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-systemd-logind.service-zzbNlW': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-polkit.service-ZHaNOZ': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-trendscout-tailnet.service-YOg4Vh': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-agent@limbforge.service-2S1JZT': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-unified-learning.service-hHXLPj': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-mobile-gateway.service-8gEKrY': Permission denied find: '/tmp/systemd-private-c1d79c13ec754067b8e0f9035892fbb7-shire-marketing-oauth-callback.service-W1aXWc': Permission denied find: '/tmp/shire-marketing-pipeline-test-2IAgvg': Permission denied find: '/run/lightdm': Permission denied find: '/run/udisks2': Permission denied find: '/run/wpa_supplicant': Permission denied find: '/run/sudo': Permission denied find: '/run/speech-dispatcher': Permission denied find: '/run/openvpn-server': Permission denied find: '/run/openvpn-client': Permission denied find: '/run/cryptsetup': Permission denied find: '/run/lvm': Permission denied find: '/run/initramfs': Permission denied find: '/home/mum': Permission denied find: '/home/kasey': Permission denied find: '/home/makenzie': Permission denied find: '/boot/efi': Permission denied find: '/lost+found': Permission denied find: '/root': Permission denied /etc/logrotate.d/shire-sentinel-alerts /etc/shire-agents/limbforge-canvas-gateway.env /etc/shire-mobile-gateway/mobile-gateway.env /run/shire-sentinel-suricata.pid