Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ COMPOSE_PROFILES=chat
# Use your own hostname behind TLS; on a separate subdomain also set
# SESSION_COOKIE_DOMAIN.
SIMPLEAUDIT_STUDIO_URL=http://localhost:8000
# Session/CSRF cookies are Secure by default. Set false ONLY for a plain-HTTP
# local replica (browsers drop Secure cookies over http://).
#SIMPLEAUDIT_SECURE_COOKIES=true
# Export Open WebUI's spans to Studio's OTLP listener. ON by default (matches
# dev and embedded `uvx simpleaudit-studio`): agent audits need it for real
# trace evidence. Set SIMPLEAUDIT_CHAT_OTLP=false to opt out. Content capture
Expand Down
14 changes: 7 additions & 7 deletions accounts/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ def bootstrap_admin_and_default_project(
username=username,
defaults={"email": email, "is_staff": True, "is_superuser": True},
)
# Always ensure the admin password matches the configured value. This makes
# the bootstrap idempotent across container restarts where the Postgres data
# volume persists (e.g. HF Spaces with non-ephemeral storage). Without this,
# a pre-existing admin user created with a different password would never be
# corrected, breaking login on subsequent starts.
user.set_password(password)
user.save(update_fields=["password"])
# Make sure the admin password matches the configured value. Only write it when
# it differs: Django ties sessions to the password hash, so re-hashing on every
# container start would sign every user out. A pre-existing admin created with a
# different password is still corrected on the next start.
if created or not user.check_password(password):
user.set_password(password)
user.save(update_fields=["password"])
if not user.is_active:
user.is_active = True
user.save(update_fields=["is_active"])
Expand Down
19 changes: 0 additions & 19 deletions audits/agentic/adapters/openwebui.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,6 @@
from .generic import normalize as _normalize


def _tool_arguments(attrs: dict[str, Any]) -> Any:
raw = attrs.get("gen_ai.tool.call.arguments") or attrs.get("openwebui.tool.arguments")
if isinstance(raw, str):
import json

try:
return json.loads(raw)
except (json.JSONDecodeError, TypeError):
return None
return raw


def normalize(spans: list[dict[str, Any]]) -> AgentTrajectory:
"""Map OpenWebUI trace payload to the provider-neutral trajectory."""
mapped = []
Expand All @@ -34,13 +22,6 @@ def normalize(spans: list[dict[str, Any]]) -> AgentTrajectory:
for source, target in aliases.items():
if source in attrs and target not in attrs:
attrs[target] = attrs[source]
# OWUI has no native data-scope attribute; synthesize one from the
# order identifier a tool call accessed, so policy.data_scope has
# real evidence to check (order:ACME-1001 and friends).
if attrs.get("gen_ai.tool.name") and not attrs.get("data_scope"):
args = _tool_arguments(attrs)
if isinstance(args, dict) and isinstance(args.get("order_id"), str):
attrs["data_scope"] = [f"order:{args['order_id']}"]
item["attributes"] = attrs
mapped.append(item)
return _normalize(mapped)
329 changes: 0 additions & 329 deletions audits/agentic/checks.py

This file was deleted.

Loading
Loading