|
| 1 | +--- |
| 2 | +// The consolidated security page a DBA or security reviewer looks for before |
| 3 | +// letting a tool near production. Deliberately honest: it states what is |
| 4 | +// enforced where (and display-level vs server-side), never more. |
| 5 | +import SectionHeader from './SectionHeader.astro'; |
| 6 | +
|
| 7 | +const SECURITY_MD = 'https://github.com/libredb/libredb-studio/blob/main/SECURITY.md'; |
| 8 | +const SEED_DOCS = 'https://github.com/libredb/libredb-studio/blob/main/docs/SEED_CONNECTIONS.md'; |
| 9 | +const OIDC_DOCS = 'https://github.com/libredb/libredb-studio/blob/main/docs/OIDC.md'; |
| 10 | +
|
| 11 | +const controls = [ |
| 12 | + { |
| 13 | + control: 'Authentication', |
| 14 | + detail: |
| 15 | + 'OpenID Connect SSO (Auth0, Keycloak, Okta, Azure AD or any OIDC provider) using Authorization Code Flow with PKCE. Sessions ride JWTs in httpOnly cookies — no tokens in localStorage.', |
| 16 | + href: OIDC_DOCS, |
| 17 | + linkLabel: 'OIDC guide', |
| 18 | + }, |
| 19 | + { |
| 20 | + control: 'Authorization', |
| 21 | + detail: |
| 22 | + 'Role-based access control with per-connection visibility scoping — a connection can be exposed to admins only, to users, or to everyone. Roles map from your identity provider claims.', |
| 23 | + }, |
| 24 | + { |
| 25 | + control: 'Database credentials', |
| 26 | + detail: |
| 27 | + 'Seed connections resolve ${ENV_VAR} placeholders at runtime, so secrets live in your environment or secret manager — never in a config file. Pair each connection with a dedicated least-privilege database account (read-only to start).', |
| 28 | + href: SEED_DOCS, |
| 29 | + linkLabel: 'Seed connections', |
| 30 | + }, |
| 31 | + { |
| 32 | + control: 'Transport', |
| 33 | + detail: |
| 34 | + 'TLS between browser and app; TLS and SSH tunnels from the app to your databases — including databases behind firewalls that never get public exposure.', |
| 35 | + }, |
| 36 | + { |
| 37 | + control: 'Data masking', |
| 38 | + detail: |
| 39 | + 'Sensitive columns (email, phone, SSN, financial data) are detected and masked across the grid, exports, and clipboard with RBAC enforcement. Masking is display-level — combine it with database-side grants for hard guarantees.', |
| 40 | + }, |
| 41 | + { |
| 42 | + control: 'Self-hosting & isolation', |
| 43 | + detail: |
| 44 | + 'Self-hosting is a first-class citizen: run it on your infrastructure, inside your network, behind your VPN. Nothing needs to leave your perimeter — including AI, which can run fully local via Ollama or LM Studio.', |
| 45 | + }, |
| 46 | + { |
| 47 | + control: 'Supply chain', |
| 48 | + detail: |
| 49 | + 'MIT-licensed source you can audit line by line. Every release ships SHA256 checksums; CI runs CodeQL and SonarCloud. Images are published to GHCR with immutable version tags.', |
| 50 | + }, |
| 51 | +]; |
| 52 | +--- |
| 53 | + |
| 54 | +<div class="mx-auto max-w-5xl"> |
| 55 | + <SectionHeader |
| 56 | + title="Security model" |
| 57 | + subtitle="What is enforced, where it is enforced, and how to reach us when something isn't." |
| 58 | + /> |
| 59 | + |
| 60 | + <div class="flex flex-col gap-px overflow-hidden border border-edge bg-edge"> |
| 61 | + { |
| 62 | + controls.map((c) => ( |
| 63 | + <article class="grid grid-cols-1 gap-2 bg-panel p-5 sm:grid-cols-[180px_1fr] sm:gap-6"> |
| 64 | + <h3 class="text-[13px] font-semibold tracking-wide text-bright uppercase">{c.control}</h3> |
| 65 | + <div> |
| 66 | + <p class="text-[13px] leading-relaxed text-muted">{c.detail}</p> |
| 67 | + {c.href && ( |
| 68 | + <a |
| 69 | + href={c.href} |
| 70 | + target="_blank" |
| 71 | + rel="noopener noreferrer" |
| 72 | + class="mt-1.5 inline-block text-[12px] text-primary hover:text-primary-bright" |
| 73 | + > |
| 74 | + {c.linkLabel} <span aria-hidden="true">→</span> |
| 75 | + </a> |
| 76 | + )} |
| 77 | + </div> |
| 78 | + </article> |
| 79 | + )) |
| 80 | + } |
| 81 | + </div> |
| 82 | + |
| 83 | + <!-- Responsible disclosure --> |
| 84 | + <section class="mt-10 border-l-2 border-warn/60 bg-panel p-5"> |
| 85 | + <h3 class="text-[15px] font-semibold text-bright">Found a vulnerability?</h3> |
| 86 | + <p class="mt-2 max-w-2xl text-[13px] leading-relaxed text-dim"> |
| 87 | + Please report it privately — not in a public issue. The disclosure process, supported versions, and response |
| 88 | + commitments live in the repository's security policy. |
| 89 | + </p> |
| 90 | + <a |
| 91 | + href={SECURITY_MD} |
| 92 | + target="_blank" |
| 93 | + rel="noopener noreferrer" |
| 94 | + class="mt-4 inline-flex items-center gap-2 rounded-md border border-edge-strong px-4 py-2 text-[13px] font-medium text-fg transition-colors hover:bg-raised" |
| 95 | + > |
| 96 | + Read SECURITY.md <span aria-hidden="true">→</span> |
| 97 | + </a> |
| 98 | + </section> |
| 99 | + |
| 100 | + <p class="mt-6 text-[13px] leading-relaxed"> |
| 101 | + <span class="sql-com">-- honest by default: if a control is display-level, this page says so.</span> |
| 102 | + </p> |
| 103 | +</div> |
| 104 | +<script |
| 105 | + type="application/json" |
| 106 | + data-export-payload="security" |
| 107 | + data-export-filename="security.json" |
| 108 | + data-export-format="json" |
| 109 | + set:html={JSON.stringify(controls.map(({ control, detail }) => ({ control, detail })))} |
| 110 | +/> |
0 commit comments