ubda-engine / app.py
UBDA Dev
Fix ZeroGPU compatibility: import spaces module and add required GPU-decorated stub
a0b38c8
Raw History Blame Contribute Delete
4.41 kB
import spaces # must be imported before anything that touches CUDA, even though this app is CPU-only
import subprocess
from pathlib import Path
import gradio as gr
ROOT = Path(__file__).parent.resolve()
BINARY_PATH = ROOT / "target" / "release" / "ubda_engine"
TRUST_MATRIX = [
["T-1", "Compromised", "Hard anomaly / intrusion interrupt", "None β€” active keys revoked, state frozen"],
["T0", "Unauthenticated", "Cold boot / sealed state", "None β€” payload & metadata encrypted"],
["T1", "Device Authenticated", "Hardware-backed passkey / attestation", "D0 β€” OS shell, public binaries, non-sensitive configs"],
["T2", "Behavioral Continuity", "Validated telemetry (T1 + BTE assertion)", "D1 β€” standard personal files, documents"],
["T3", "High Assurance", "Hardware biometric / local PIN (T2 + step-up)", "D2 β€” financial, medical, private records"],
["T4", "Critical Elevation", "Hardware HSM / out-of-band token (T3 + elevation)", "D3 β€” root signing keys, master vault seeds"],
]
ARCHITECTURE_NOTE = """
**UBDA (Unified Behavioral Data Access) β€” V1.2-alpha**
This is a prototype capability-based access-control engine written in Rust. A
software *Behavioral Trust Engine* can only ever propose a trust level; a
separate, hardware-style *Key Authority* independently validates that trust
level against a resource's data classification before it signs a short-lived,
single-use Data Access Capability (DAC). A *Key Broker* then re-verifies the
DAC's signature, expiry, trust requirement, operation, and session binding β€”
and rejects replay β€” before deriving an ephemeral session key.
Click **Run protocol walkthrough** below to execute the actual compiled Rust
binary and watch it move through all six stages of the protocol: reaching
T2 via behavioral continuity, a rejected over-privileged request, a full
issue β†’ verify β†’ derive-key cycle, a blocked replay attempt, a blocked
signature-tampering attempt, and a compromise lockout + recovery reset.
*(First click may take a little longer β€” the engine compiles the Rust source
the first time it's needed, then reuses the built binary after that.)*
⚠️ Prototype / educational project β€” not a production security product.
Source: see the linked GitHub repository.
"""
@spaces.GPU
def _zerogpu_keepalive():
"""No-op. This Space is CPU-only (compiling/running a Rust binary), but
ZeroGPU hardware requires at least one @spaces.GPU-decorated function to
exist or the Space fails to initialize. This satisfies that requirement
without ever actually requesting GPU time for real work."""
return None
def ensure_built() -> str | None:
"""Compile the Rust engine if it hasn't been built yet. Returns an error string, or None on success."""
if BINARY_PATH.exists():
return None
try:
result = subprocess.run(
["cargo", "build", "--release", "--locked"],
cwd=str(ROOT),
capture_output=True,
text=True,
timeout=300,
)
if result.returncode != 0 or not BINARY_PATH.exists():
return f"Build failed:\n{result.stdout}\n{result.stderr}"
return None
except Exception as exc: # noqa: BLE001
return f"Build failed: {exc}"
def run_walkthrough():
build_error = ensure_built()
if build_error:
return build_error
try:
result = subprocess.run(
[str(BINARY_PATH)],
capture_output=True,
text=True,
timeout=15,
)
output = result.stdout
if result.returncode != 0:
output += f"\n\n[process exited with code {result.returncode}]\n{result.stderr}"
return output
except Exception as exc: # noqa: BLE001
return f"Failed to run the engine: {exc}"
with gr.Blocks(title="UBDA Engine Demo") as demo:
gr.Markdown(ARCHITECTURE_NOTE)
run_btn = gr.Button("β–Ά Run protocol walkthrough", variant="primary")
output_box = gr.Textbox(label="Engine output", lines=24, show_copy_button=True)
run_btn.click(fn=run_walkthrough, outputs=output_box)
gr.Markdown("### Trust-state matrix")
gr.Dataframe(
headers=["State", "Name", "Minimum gatekeeper requirement", "Accessible data classification"],
value=TRUST_MATRIX,
interactive=False,
wrap=True,
)
if __name__ == "__main__":
demo.launch()