Add security audit report and infrastructure cost analysis

Standalone security report (security_report.py) covering 6 supply chain
and build pipeline findings from the performance engagement. Add infra
cost section to exec view showing $10K → $1.1K/mo projection based on
D48s_v5 node packing at 4 GB vs 32 GB per pod.
This commit is contained in:
Kevin Turcios 2026-04-15 18:22:07 -05:00
parent f8281a24a0
commit e65b8a3564
2 changed files with 1079 additions and 0 deletions

View file

@ -0,0 +1,177 @@
{
"core_product_base": "https://github.com/Unstructured-IO/core-product/pull",
"github_workflows_base": "https://github.com/Unstructured-IO/github-workflows/pull",
"platform_libs_base": "https://github.com/Unstructured-IO/platform-libs/pull",
"findings": [
{
"id": "SEC-001",
"title": "Lockfile Bypass via uv pip install in Docker Builds",
"severity": "critical",
"category": "Supply Chain",
"status": "fixed",
"fixed_by": "Unstructured (PR #1465)",
"repo": "core-product",
"pr": 1465,
"duration_exposed": "~2 months",
"description": "Core-product's uv migration used `uv pip install` in Docker builds, which completely bypasses the lockfile. The uv docs explicitly state: 'It is not recommended to modify the project environment manually with uv pip install.'",
"impact": [
"Builds were non-reproducible for approximately 2 months — different builds could get different dependency versions",
"Renovate CVE fix PRs were merged but never reached production images — the team's security posture on paper looked fine, but production was running vulnerable code",
"torch silently pulled CUDA variants (~2.5 GB of unnecessary nvidia packages)",
"The uv pip install pattern was repeated 15+ times across CI workflows, docker-publish, triton, and process-render workflows"
],
"code_before": "uv venv --python 3.12\nuv pip install pip setuptools wheel types-requests\n# ... plus manual caching, credential scripts",
"code_after": "# uses: astral-sh/setup-uv@v7\nuv sync --locked",
"context": "Unstructured processes sensitive documents (PDFs, emails, financial records, medical documents) for customers in regulated industries (HIPAA, SOC 2, PCI-DSS). Customer security audits would flag non-reproducible builds."
},
{
"id": "SEC-002",
"title": "CVE Remediation Not Reaching Production",
"severity": "high",
"category": "Vulnerability Management",
"status": "fixed",
"fixed_by": "Unstructured (PRs #1423, #1434, #1437)",
"repo": "core-product",
"pr": null,
"duration_exposed": "Unknown",
"description": "Because of the lockfile bypass (SEC-001), CVE remediation PRs that were merged into main never actually changed what was installed in production Docker images. The lockfile was updated but uv pip install ignored it.",
"impact": [
"CVE-2026-28351 (pypdf) — remediated in PR #1423 but not deployed until lockfile bypass was fixed",
"General CVE remediation in PR #1434 similarly delayed",
"Grype security scanner fix in PR #1437",
"Security posture appeared healthy (PRs merged, Renovate active) while production ran vulnerable dependencies"
],
"code_before": null,
"code_after": null,
"context": "This is a direct consequence of SEC-001. The team was doing the right thing (merging CVE fixes promptly) but the broken build pipeline negated their efforts."
},
{
"id": "SEC-003",
"title": "pip.conf Bypass in CI Workflows",
"severity": "medium",
"category": "Build Pipeline",
"status": "fixed",
"fixed_by": "Codeflash (PR #361)",
"repo": "github-workflows",
"pr": 361,
"duration_exposed": null,
"description": "The shared github-workflows configure-pypi step writes a .venv/pip.conf at the work-dir level, but in uv workspace mode the .venv is at the repo root. This caused the private Azure DevOps PyPI index credentials to be written to the wrong location, breaking authentication for internal packages.",
"impact": [
"Internal packages (utic-instrumentation, unstructured-prompts) failed to resolve in uv workspace mode",
"Workaround required environment variable credential injection",
"Blocked uv workspace migration for platform-libs"
],
"code_before": null,
"code_after": null,
"context": "Discovered while building the uv workspace POC for platform-libs. The pip.conf was being written to a location uv doesn't read in workspace mode."
},
{
"id": "SEC-004",
"title": "No uv Version Pinning Across Repos",
"severity": "medium",
"category": "Build Reproducibility",
"status": "open",
"fixed_by": null,
"repo": "org-wide",
"pr": null,
"duration_exposed": "Ongoing",
"description": "None of Unstructured's 7 repos use required-version in [tool.uv]. CI uses setup-uv versions ranging from v5 to v7 across repos. Different uv versions can produce different lockfile resolutions.",
"impact": [
"Different developers on different uv versions can produce different lockfiles",
"CI uses setup-uv versions ranging from v5 to v7 — inconsistent resolution behavior",
"No .gitattributes or documented process for handling uv.lock merge conflicts (main repo has a 1.4 MB lockfile)",
"Version constraint mismatch: unstructured-inference requires Python >=3.12,<3.13 while unstructured allows >=3.11"
],
"code_before": null,
"code_after": null,
"context": "This creates a vector for lockfile divergence. When two developers generate different lockfiles, one of them may inadvertently introduce a vulnerable dependency version."
},
{
"id": "SEC-005",
"title": "uv pip Resolution Differences (Dependency Confusion)",
"severity": "medium",
"category": "Supply Chain",
"status": "open",
"fixed_by": null,
"repo": "unstructured",
"pr": 4216,
"duration_exposed": null,
"description": "numba>=0.60.0 was resolved by uv to version 0.53.1 (Python <3.10 only), while pip correctly picked 0.63.1 (Python 3.12 compatible). The resolution behavior differences between uv and pip are a real risk during migration.",
"impact": [
"Wrong package version installed silently — no error, just incorrect behavior",
"uv's resolution algorithm differs from pip in edge cases involving Python version markers",
"Could lead to installing packages with known vulnerabilities if the wrong version is selected"
],
"code_before": null,
"code_after": null,
"context": "Discovered during the unstructured repo's uv migration. This class of bug is subtle and hard to catch — the install succeeds but the wrong version is used."
},
{
"id": "SEC-006",
"title": "Socket Security Org-Level Ruleset",
"severity": "info",
"category": "Positive Control",
"status": "active",
"fixed_by": null,
"repo": "org-wide",
"pr": null,
"duration_exposed": null,
"description": "Unstructured-IO has an org-level GitHub ruleset (ID 14342252) requiring the Socket Security GitHub App to scan all PRs for supply chain security issues in dependencies before merging to main.",
"impact": [
"All PRs across the org are scanned for dependency supply chain issues",
"Cannot be disabled at the repo level — enforced org-wide",
"Catches new vulnerable dependencies before they reach main"
],
"code_before": null,
"code_after": null,
"context": "This is an effective control. However, it only covers new PRs — it does not retroactively scan existing dependencies in the lockfile, and it cannot catch the lockfile bypass issue (SEC-001) since uv pip install doesn't change the lockfile."
}
],
"summary": {
"total_findings": 6,
"critical": 1,
"high": 1,
"medium": 3,
"info": 1,
"fixed": 3,
"open": 2,
"positive": 1
},
"recommendations": [
{
"priority": 1,
"title": "Pin uv version across all repos",
"description": "Add required-version to [tool.uv] in every pyproject.toml. Standardize setup-uv version in CI. Add .gitattributes for uv.lock merge strategy.",
"effort": "Low",
"impact": "High"
},
{
"priority": 2,
"title": "Audit all CI workflows for uv pip install usage",
"description": "Search all repos for remaining uv pip install patterns and replace with uv sync --locked. The pattern was found 15+ times across workflows.",
"effort": "Medium",
"impact": "Critical"
},
{
"priority": 3,
"title": "Implement lockfile verification in CI",
"description": "Add a CI step that runs uv lock --check to verify the lockfile is up to date. Fail the build if it diverges.",
"effort": "Low",
"impact": "High"
},
{
"priority": 4,
"title": "Pin GitHub Action versions to immutable SHAs",
"description": "Replace mutable tags (@v6, @v7) with full commit SHAs or immutable release tags across all workflow files.",
"effort": "Low",
"impact": "Medium"
},
{
"priority": 5,
"title": "Establish dependency audit cadence",
"description": "Run uv pip audit or equivalent on a schedule. Socket Security covers new PRs but not the existing dependency tree.",
"effort": "Low",
"impact": "Medium"
}
]
}

View file

@ -0,0 +1,902 @@
"""Unstructured x Codeflash — Security Audit Report
Standalone report covering supply chain and build pipeline security
findings identified during the performance engagement.
"""
import json
from pathlib import Path
from dash import Dash, html
from theme import (
ACCENT,
AMBER,
BG,
BLUE,
CARD,
CARD_BG,
CARD_BORDER,
DARK,
FONT,
GRAY,
GREEN,
GRID_OVERLAY,
LIGHT_GRAY,
LIGHT_GREEN,
LIGHT_RED,
MONO,
PURPLE,
RED,
SLATE,
WHITE,
)
# ── Data ────────────────────────────────────────────────────────────────────
_DATA = json.loads((Path(__file__).parent / "security_data.json").read_text())
FINDINGS = _DATA["findings"]
SUMMARY = _DATA["summary"]
RECOMMENDATIONS = _DATA["recommendations"]
CORE_PRODUCT_BASE = _DATA["core_product_base"]
GITHUB_WORKFLOWS_BASE = _DATA["github_workflows_base"]
SEVERITY_COLORS = {
"critical": RED,
"high": "#f97316", # orange
"medium": AMBER,
"low": BLUE,
"info": GRAY,
}
SEVERITY_BG = {
"critical": LIGHT_RED,
"high": "rgba(249,115,22,0.12)",
"medium": "rgba(251,191,36,0.12)",
"low": "rgba(96,165,250,0.12)",
"info": "rgba(161,161,170,0.12)",
}
STATUS_COLORS = {
"fixed": GREEN,
"open": AMBER,
"active": BLUE,
}
# ── Helpers ──────────────────────────────────────────────────────────────────
def section(title, subtitle=None):
children = [
html.H2(
title,
style={
"fontSize": "22px",
"fontWeight": "700",
"color": SLATE,
"margin": "0",
"fontFamily": FONT,
"letterSpacing": "-0.01em",
},
)
]
if subtitle:
children.append(
html.P(
subtitle,
style={
"fontSize": "14px",
"color": GRAY,
"margin": "6px 0 0",
"lineHeight": "1.5",
},
)
)
return html.Div(children, style={"margin": "56px 0 24px"})
def card(children, **kw):
style = {**CARD}
for k, v in kw.items():
style[k] = v
return html.Div(children, style=style)
def severity_badge(severity):
return html.Span(
severity.upper(),
style={
"fontSize": "11px",
"fontWeight": "700",
"color": SEVERITY_COLORS.get(severity, GRAY),
"background": SEVERITY_BG.get(severity, "transparent"),
"padding": "3px 10px",
"borderRadius": "999px",
"letterSpacing": "0.05em",
},
)
def status_badge(status):
return html.Span(
status.upper(),
style={
"fontSize": "11px",
"fontWeight": "700",
"color": STATUS_COLORS.get(status, GRAY),
"background": "transparent",
"border": f"1px solid {STATUS_COLORS.get(status, GRAY)}",
"padding": "2px 10px",
"borderRadius": "999px",
"letterSpacing": "0.05em",
},
)
def finding_card(f):
"""Render a single finding as a card."""
sev = f["severity"]
border_color = SEVERITY_COLORS.get(sev, GRAY)
# Header: ID + title + badges
header = html.Div(
[
html.Div(
[
html.Span(
f["id"],
style={
"fontFamily": MONO,
"fontSize": "13px",
"color": LIGHT_GRAY,
"marginRight": "12px",
},
),
html.Span(
f["title"],
style={
"fontWeight": "700",
"color": SLATE,
"fontSize": "16px",
},
),
],
style={"flex": "1"},
),
html.Div(
[
severity_badge(sev),
status_badge(f["status"]),
],
style={"display": "flex", "gap": "8px", "alignItems": "center"},
),
],
style={
"display": "flex",
"alignItems": "center",
"gap": "16px",
"marginBottom": "16px",
"flexWrap": "wrap",
},
)
# Metadata row
meta_items = []
if f.get("repo"):
meta_items.append(
html.Span(
[
html.Span("Repo: ", style={"color": LIGHT_GRAY}),
html.Span(
f["repo"],
style={"color": SLATE, "fontWeight": "600"},
),
],
)
)
if f.get("category"):
meta_items.append(
html.Span(
[
html.Span("Category: ", style={"color": LIGHT_GRAY}),
html.Span(
f["category"],
style={"color": SLATE, "fontWeight": "600"},
),
],
)
)
if f.get("duration_exposed"):
meta_items.append(
html.Span(
[
html.Span("Exposed: ", style={"color": LIGHT_GRAY}),
html.Span(
f["duration_exposed"],
style={"color": RED, "fontWeight": "600"},
),
],
)
)
if f.get("fixed_by"):
meta_items.append(
html.Span(
[
html.Span("Fixed by: ", style={"color": LIGHT_GRAY}),
html.Span(
f["fixed_by"],
style={"color": GREEN, "fontWeight": "600"},
),
],
)
)
meta = html.Div(
meta_items,
style={
"display": "flex",
"gap": "24px",
"flexWrap": "wrap",
"fontSize": "13px",
"marginBottom": "16px",
"paddingBottom": "16px",
"borderBottom": f"1px solid {CARD_BORDER}",
},
)
# Description
desc = html.P(
f["description"],
style={
"color": GRAY,
"fontSize": "14px",
"lineHeight": "1.7",
"margin": "0 0 16px",
},
)
# Impact list
impact = html.Div(
[
html.Div(
"Impact",
style={
"fontSize": "12px",
"fontWeight": "700",
"color": ACCENT,
"textTransform": "uppercase",
"letterSpacing": "0.05em",
"marginBottom": "8px",
},
),
html.Ul(
[
html.Li(
i,
style={
"fontSize": "13px",
"color": GRAY,
"lineHeight": "1.6",
"marginBottom": "4px",
},
)
for i in f["impact"]
],
style={
"paddingLeft": "20px",
"margin": "0",
},
),
],
style={"marginBottom": "16px"},
)
children = [header, meta, desc, impact]
# Code before/after
if f.get("code_before") or f.get("code_after"):
code_section = html.Div(
style={
"display": "flex",
"gap": "16px",
"flexWrap": "wrap",
"marginBottom": "16px",
},
children=[
*(
[
html.Div(
[
html.Div(
"BEFORE",
style={
"fontSize": "11px",
"fontWeight": "700",
"color": RED,
"letterSpacing": "0.1em",
"marginBottom": "8px",
},
),
html.Pre(
f["code_before"],
style={
"fontFamily": MONO,
"fontSize": "12px",
"color": SLATE,
"background": "rgba(0,0,0,0.3)",
"padding": "16px",
"borderRadius": "8px",
"overflow": "auto",
"margin": "0",
"border": f"1px solid {CARD_BORDER}",
"whiteSpace": "pre-wrap",
},
),
],
style={"flex": "1", "minWidth": "280px"},
)
]
if f.get("code_before")
else []
),
*(
[
html.Div(
[
html.Div(
"AFTER",
style={
"fontSize": "11px",
"fontWeight": "700",
"color": GREEN,
"letterSpacing": "0.1em",
"marginBottom": "8px",
},
),
html.Pre(
f["code_after"],
style={
"fontFamily": MONO,
"fontSize": "12px",
"color": SLATE,
"background": "rgba(0,0,0,0.3)",
"padding": "16px",
"borderRadius": "8px",
"overflow": "auto",
"margin": "0",
"border": f"1px solid {CARD_BORDER}",
"whiteSpace": "pre-wrap",
},
),
],
style={"flex": "1", "minWidth": "280px"},
)
]
if f.get("code_after")
else []
),
],
)
children.append(code_section)
# Context
if f.get("context"):
children.append(
html.P(
f["context"],
style={
"color": LIGHT_GRAY,
"fontSize": "13px",
"lineHeight": "1.6",
"margin": "0",
"fontStyle": "italic",
},
)
)
return html.Div(
children,
style={
**CARD,
"marginBottom": "20px",
"borderLeft": f"4px solid {border_color}",
},
)
def recommendation_card(r):
"""Render a single recommendation."""
effort_color = {
"Low": GREEN,
"Medium": AMBER,
"High": RED,
}.get(r["effort"], GRAY)
impact_color = {
"Critical": RED,
"High": "#f97316",
"Medium": AMBER,
"Low": BLUE,
}.get(r["impact"], GRAY)
return card(
[
html.Div(
[
html.Div(
str(r["priority"]),
style={
"fontSize": "24px",
"fontWeight": "800",
"color": ACCENT,
"lineHeight": "1",
"minWidth": "32px",
},
),
html.Div(
[
html.Div(
r["title"],
style={
"fontWeight": "700",
"color": SLATE,
"fontSize": "15px",
"marginBottom": "8px",
},
),
html.P(
r["description"],
style={
"color": GRAY,
"fontSize": "14px",
"lineHeight": "1.6",
"margin": "0",
},
),
],
style={"flex": "1"},
),
html.Div(
[
html.Div(
[
html.Span(
"Effort: ",
style={
"color": LIGHT_GRAY,
"fontSize": "12px",
},
),
html.Span(
r["effort"],
style={
"color": effort_color,
"fontSize": "12px",
"fontWeight": "700",
},
),
],
style={"marginBottom": "4px"},
),
html.Div(
[
html.Span(
"Impact: ",
style={
"color": LIGHT_GRAY,
"fontSize": "12px",
},
),
html.Span(
r["impact"],
style={
"color": impact_color,
"fontSize": "12px",
"fontWeight": "700",
},
),
],
),
],
style={
"minWidth": "100px",
"textAlign": "right",
},
),
],
style={
"display": "flex",
"gap": "16px",
"alignItems": "flex-start",
},
),
],
marginBottom="12px",
)
# ── App ──────────────────────────────────────────────────────────────────────
app = Dash(
__name__,
meta_tags=[
{"name": "viewport", "content": "width=device-width, initial-scale=1"},
{
"property": "og:title",
"content": "Unstructured x Codeflash — Security Audit",
},
],
suppress_callback_exceptions=True,
)
app.title = "Unstructured x Codeflash — Security Audit"
app.index_string = """<!DOCTYPE html>
<html>
<head>
{%metas%}
<title>{%title%}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet">
{%favicon%}
{%css%}
</head>
<body>
{%app_entry%}
<footer>
{%config%}
{%scripts%}
{%renderer%}
</footer>
</body>
</html>"""
app.layout = html.Div(
style={
"background": BG,
"minHeight": "100vh",
"fontFamily": FONT,
"position": "relative",
},
children=[
# ── Grid overlay ──
html.Div(style=GRID_OVERLAY),
# ── Hero ──
html.Div(
style={
"background": f"linear-gradient(135deg, {BG} 0%, #1a0f0f 50%, {BG} 100%)",
"padding": "60px 24px 52px",
"textAlign": "center",
"borderBottom": f"1px solid {CARD_BORDER}",
"position": "relative",
"zIndex": "1",
},
children=[
html.Div(
style={
"display": "flex",
"alignItems": "center",
"justifyContent": "center",
"gap": "20px",
"marginBottom": "24px",
},
children=[
html.Img(
src="/assets/codeflash.svg",
style={"height": "32px"},
),
html.Span(
"\u00d7",
style={
"fontSize": "24px",
"fontWeight": "300",
"color": LIGHT_GRAY,
},
),
html.Img(
src="/assets/unstructured_logo.jpg",
style={
"height": "36px",
"borderRadius": "6px",
},
),
],
),
html.H1(
"Security Audit",
style={
"color": WHITE,
"fontSize": "36px",
"fontWeight": "800",
"margin": "0",
"letterSpacing": "-0.02em",
"fontFamily": FONT,
},
),
html.P(
"Supply chain and build pipeline findings from the performance engagement",
style={
"color": GRAY,
"fontSize": "17px",
"margin": "12px auto 0",
"maxWidth": "700px",
},
),
html.Div(
style={
"marginTop": "24px",
"display": "flex",
"justifyContent": "center",
"gap": "24px",
"flexWrap": "wrap",
},
children=[
html.Span(
"April 2026",
style={"color": LIGHT_GRAY, "fontSize": "13px"},
),
html.Span("|", style={"color": LIGHT_GRAY}),
html.Span(
f"{SUMMARY['total_findings']} findings",
style={"color": LIGHT_GRAY, "fontSize": "13px"},
),
html.Span("|", style={"color": LIGHT_GRAY}),
html.Span(
f"{SUMMARY['fixed']} fixed, {SUMMARY['open']} open",
style={"color": LIGHT_GRAY, "fontSize": "13px"},
),
],
),
],
),
# ── Content ──
html.Div(
style={
"maxWidth": "960px",
"margin": "0 auto",
"padding": "0 24px 80px",
"position": "relative",
"zIndex": "1",
},
children=[
# ── Summary metrics ──
html.Div(
style={
"display": "flex",
"gap": "20px",
"flexWrap": "wrap",
"marginTop": "-40px",
"position": "relative",
"zIndex": "1",
},
children=[
html.Div(
[
html.Div(
str(SUMMARY["critical"]),
style={
"fontSize": "42px",
"fontWeight": "800",
"color": RED,
"lineHeight": "1",
},
),
html.Div(
"Critical",
style={
"fontSize": "15px",
"fontWeight": "600",
"color": SLATE,
"marginTop": "8px",
},
),
html.Div(
"Lockfile bypass in Docker builds",
style={
"fontSize": "13px",
"color": GRAY,
"marginTop": "4px",
},
),
],
style={
"background": CARD_BG,
"borderRadius": "16px",
"padding": "32px 24px",
"textAlign": "center",
"flex": "1",
"minWidth": "200px",
"border": f"1px solid {CARD_BORDER}",
},
),
html.Div(
[
html.Div(
str(SUMMARY["high"]),
style={
"fontSize": "42px",
"fontWeight": "800",
"color": "#f97316",
"lineHeight": "1",
},
),
html.Div(
"High",
style={
"fontSize": "15px",
"fontWeight": "600",
"color": SLATE,
"marginTop": "8px",
},
),
html.Div(
"CVE patches not reaching production",
style={
"fontSize": "13px",
"color": GRAY,
"marginTop": "4px",
},
),
],
style={
"background": CARD_BG,
"borderRadius": "16px",
"padding": "32px 24px",
"textAlign": "center",
"flex": "1",
"minWidth": "200px",
"border": f"1px solid {CARD_BORDER}",
},
),
html.Div(
[
html.Div(
str(SUMMARY["medium"]),
style={
"fontSize": "42px",
"fontWeight": "800",
"color": AMBER,
"lineHeight": "1",
},
),
html.Div(
"Medium",
style={
"fontSize": "15px",
"fontWeight": "600",
"color": SLATE,
"marginTop": "8px",
},
),
html.Div(
"Build reproducibility and resolution gaps",
style={
"fontSize": "13px",
"color": GRAY,
"marginTop": "4px",
},
),
],
style={
"background": CARD_BG,
"borderRadius": "16px",
"padding": "32px 24px",
"textAlign": "center",
"flex": "1",
"minWidth": "200px",
"border": f"1px solid {CARD_BORDER}",
},
),
],
),
# ── Executive Summary ──
section(
"Executive Summary",
"These findings were discovered incidentally during the performance engagement, "
"not through a dedicated security audit.",
),
card(
[
html.P(
[
"While profiling core-product's memory and latency, we identified "
"supply chain and build pipeline issues that affect the security "
"posture of Unstructured's production deployments. The most critical "
"finding — a ",
html.Span(
"lockfile bypass in Docker builds",
style={"fontWeight": "700", "color": RED},
),
" — meant that CVE remediation PRs merged by the team were ",
html.Span(
"never actually deployed to production",
style={"fontWeight": "700", "color": SLATE},
),
". This has since been fixed by the Unstructured team.",
],
style={
"color": GRAY,
"fontSize": "15px",
"lineHeight": "1.7",
"margin": "0 0 16px",
},
),
html.P(
"The remaining open findings relate to build reproducibility: "
"inconsistent uv versions across repos and resolution behavior "
"differences that could reintroduce similar issues.",
style={
"color": GRAY,
"fontSize": "15px",
"lineHeight": "1.7",
"margin": "0",
},
),
]
),
# ── Findings ──
section("Findings"),
*[finding_card(f) for f in FINDINGS],
# ── Recommendations ──
section(
"Recommendations",
"Prioritized by impact-to-effort ratio.",
),
*[recommendation_card(r) for r in RECOMMENDATIONS],
# ── Footer ──
html.Div(
style={
"textAlign": "center",
"marginTop": "64px",
"paddingTop": "24px",
"borderTop": f"1px solid {CARD_BORDER}",
},
children=[
html.Div(
style={
"display": "flex",
"alignItems": "center",
"justifyContent": "center",
"gap": "10px",
"marginBottom": "4px",
},
children=[
html.Img(
src="/assets/codeflash.svg",
style={"height": "16px"},
),
html.Span(
"\u00d7",
style={
"fontSize": "13px",
"color": LIGHT_GRAY,
},
),
html.Img(
src="/assets/unstructured_logo.jpg",
style={
"height": "20px",
"borderRadius": "3px",
},
),
],
),
html.P(
"Security Audit — April 2026",
style={
"color": LIGHT_GRAY,
"fontSize": "13px",
"margin": "0",
},
),
],
),
],
),
],
)
server = app.server
if __name__ == "__main__":
app.run(debug=True, port=8051)