Models¶
models ¶
SQLAlchemy ORM models for Shoreguard.
Base ¶
Bases: DeclarativeBase
Base class for all Shoreguard models.
Gateway ¶
Bases: Base
A registered OpenShell gateway.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
name |
Mapped[str]
|
Unique gateway name (max 253 chars). |
endpoint |
Mapped[str]
|
Host:port of the gateway gRPC endpoint. |
scheme |
Mapped[str]
|
Connection scheme ( |
auth_mode |
Mapped[str | None]
|
Optional authentication mode identifier. |
ca_cert |
Mapped[bytes | None]
|
Optional CA certificate bytes for mTLS. |
client_cert |
Mapped[bytes | None]
|
Optional client certificate bytes for mTLS. |
client_key |
Mapped[bytes | None]
|
Optional client private key bytes for mTLS. |
metadata_json |
Mapped[str | None]
|
Optional JSON-encoded metadata blob. |
description |
Mapped[str | None]
|
Optional free-text description of the gateway's purpose. |
labels_json |
Mapped[str | None]
|
Optional JSON-encoded key-value labels for filtering. |
registered_at |
Mapped[datetime]
|
Timestamp when the gateway was registered. |
last_seen |
Mapped[datetime | None]
|
Timestamp of the most recent health check. |
last_status |
Mapped[str]
|
Last known health status string. |
User ¶
Bases: Base
A user account with email/password authentication.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
email |
Mapped[str]
|
Unique email address (max 254 chars). |
hashed_password |
Mapped[str | None]
|
Bcrypt-hashed password, or |
role |
Mapped[str]
|
Global role ( |
is_active |
Mapped[bool]
|
Whether the account is enabled. |
invite_token_hash |
Mapped[str | None]
|
SHA-256 hash of the invite token, if pending. |
created_at |
Mapped[datetime]
|
Timestamp when the user was created. |
oidc_provider |
Mapped[str | None]
|
Name of the OIDC provider, or |
oidc_sub |
Mapped[str | None]
|
OIDC subject identifier, or |
ServicePrincipal ¶
Bases: Base
A service principal (API key) for programmatic access.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
name |
Mapped[str]
|
Unique human-readable name (max 100 chars). |
key_hash |
Mapped[str]
|
SHA-256 hash of the API key. |
key_prefix |
Mapped[str | None]
|
First 12 characters of the key for identification. |
role |
Mapped[str]
|
Global role ( |
created_by |
Mapped[int | None]
|
FK to the user who created this principal, or |
created_at |
Mapped[datetime]
|
Timestamp when the principal was created. |
last_used |
Mapped[datetime | None]
|
Timestamp of the most recent API call, or |
expires_at |
Mapped[datetime | None]
|
Optional expiry timestamp; |
UserGatewayRole ¶
Bases: Base
A per-gateway role override for a user.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
user_id |
Mapped[int]
|
FK to the user. |
gateway_id |
Mapped[int]
|
FK to the gateway. |
role |
Mapped[str]
|
Scoped role for this user on this gateway. |
SPGatewayRole ¶
Bases: Base
A per-gateway role override for a service principal.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
sp_id |
Mapped[int]
|
FK to the service principal. |
gateway_id |
Mapped[int]
|
FK to the gateway. |
role |
Mapped[str]
|
Scoped role for this principal on this gateway. |
Group ¶
Bases: Base
A named collection of users for group-based RBAC.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
name |
Mapped[str]
|
Unique group name (max 100 chars). |
description |
Mapped[str | None]
|
Optional human-readable description. |
role |
Mapped[str]
|
Global group role ( |
created_at |
Mapped[datetime]
|
Timestamp when the group was created. |
GroupMember ¶
Bases: Base
Junction table linking users to groups.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
group_id |
Mapped[int]
|
FK to the group. |
user_id |
Mapped[int]
|
FK to the user. |
GroupGatewayRole ¶
Bases: Base
A per-gateway role override for a group.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
group_id |
Mapped[int]
|
FK to the group. |
gateway_id |
Mapped[int]
|
FK to the gateway. |
role |
Mapped[str]
|
Scoped role for this group on this gateway. |
AuditEntry ¶
Bases: Base
A persistent audit log entry for state-changing operations.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
timestamp |
Mapped[datetime]
|
When the action occurred. |
actor |
Mapped[str]
|
Email or service principal name of the acting identity. |
actor_role |
Mapped[str]
|
Effective role at time of action. |
action |
Mapped[str]
|
Machine-readable action identifier. |
resource_type |
Mapped[str]
|
Type of resource affected (e.g. |
resource_id |
Mapped[str]
|
Identifier of the affected resource. |
gateway_name |
Mapped[str | None]
|
Human-readable gateway name, if applicable. |
gateway_id |
Mapped[int | None]
|
FK to the gateway, or |
detail |
Mapped[str | None]
|
Optional free-text detail or JSON payload. |
client_ip |
Mapped[str | None]
|
IP address of the requesting client, if available. |
SandboxMeta ¶
Bases: Base
ShoreGuard-side metadata for a sandbox (labels, description).
Sandboxes live on the OpenShell gateway; this table stores metadata that ShoreGuard manages independently.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
gateway_name |
Mapped[str]
|
Name of the gateway the sandbox belongs to. |
sandbox_name |
Mapped[str]
|
Name of the sandbox (unique per gateway). |
description |
Mapped[str | None]
|
Optional free-text description. |
labels_json |
Mapped[str | None]
|
Optional JSON-encoded key-value labels. |
created_at |
Mapped[datetime]
|
Timestamp when the metadata was first stored. |
updated_at |
Mapped[datetime | None]
|
Timestamp of the last metadata update. |
Webhook ¶
Bases: Base
A webhook endpoint for event notifications.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
url |
Mapped[str]
|
Target URL for POST requests (max 2048 chars). |
secret |
Mapped[str]
|
HMAC-SHA256 signing secret. |
event_types |
Mapped[str]
|
JSON-encoded list of subscribed event types. |
is_active |
Mapped[bool]
|
Whether the webhook is enabled. |
channel_type |
Mapped[str]
|
Channel type (generic, slack, discord, email). |
extra_config |
Mapped[str | None]
|
Optional JSON config for channel-specific settings. |
created_by |
Mapped[str]
|
Email or service principal name of the creator. |
created_at |
Mapped[datetime]
|
Timestamp when the webhook was created. |
WebhookDelivery ¶
Bases: Base
A delivery attempt for a webhook event.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
webhook_id |
Mapped[int]
|
FK to the webhook that was triggered. |
event_type |
Mapped[str]
|
The event type that triggered the delivery. |
payload_json |
Mapped[str]
|
JSON-encoded event payload. |
status |
Mapped[str]
|
Delivery status ( |
response_code |
Mapped[int | None]
|
HTTP response code from the target, if any. |
error_message |
Mapped[str | None]
|
Error details on failure, if any. |
attempt |
Mapped[int]
|
Current attempt number (1-based). |
created_at |
Mapped[datetime]
|
Timestamp when the delivery was created. |
delivered_at |
Mapped[datetime | None]
|
Timestamp when delivery succeeded, if any. |
PolicyPin ¶
Bases: Base
A policy pin that locks a sandbox's policy at a specific version.
When a pin is active, policy updates and draft approvals are blocked until the pin is removed or expires.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
gateway_name |
Mapped[str]
|
Name of the gateway the sandbox belongs to. |
sandbox_name |
Mapped[str]
|
Name of the pinned sandbox. |
pinned_version |
Mapped[int]
|
The policy version that is locked. |
pinned_by |
Mapped[str]
|
Email or service principal name of the actor who set the pin. |
reason |
Mapped[str | None]
|
Optional human-readable reason for pinning. |
pinned_at |
Mapped[datetime]
|
Timestamp when the pin was created. |
expires_at |
Mapped[datetime | None]
|
Optional expiry timestamp; |
ApprovalWorkflow ¶
Bases: Base
A multi-stage approval (quorum) configuration for a sandbox.
When a workflow exists, POST .../approvals/{chunk_id}/approve records
a vote rather than calling the upstream gateway directly. The upstream
approve fires only when the configured quorum is reached.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
gateway_name |
Mapped[str]
|
Gateway the sandbox belongs to. |
sandbox_name |
Mapped[str]
|
Sandbox this workflow applies to. |
required_approvals |
Mapped[int]
|
Number of distinct approve votes needed. |
required_roles_json |
Mapped[str]
|
JSON array of roles eligible to vote (empty = any). |
distinct_actors |
Mapped[bool]
|
If true, the same actor cannot vote twice. |
escalation_timeout_minutes |
Mapped[int | None]
|
Fire |
created_by |
Mapped[str]
|
Identity of the admin who configured the workflow. |
created_at |
Mapped[datetime]
|
When the workflow was created. |
updated_at |
Mapped[datetime]
|
When the workflow was last updated. |
ApprovalDecision ¶
Bases: Base
A single vote cast against an approval chunk under a workflow.
Append-only log; pending/approved/rejected state is derived from the row set. Rows are cleared once the upstream gateway approve fires (on quorum met) or the chunk is rejected.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
workflow_id |
Mapped[int]
|
FK to the active workflow configuration. |
gateway_name |
Mapped[str]
|
Gateway the sandbox belongs to (denormalised for lookup). |
sandbox_name |
Mapped[str]
|
Sandbox the chunk belongs to (denormalised for lookup). |
chunk_id |
Mapped[str]
|
The draft chunk being voted on. |
actor |
Mapped[str]
|
Identity of the voting user. |
role |
Mapped[str]
|
Role the voter held at vote time. |
decision |
Mapped[str]
|
|
comment |
Mapped[str | None]
|
Optional free-text comment. |
created_at |
Mapped[datetime]
|
When the vote was cast. |
PolicyApplyProposal ¶
Bases: Base
A YAML policy apply proposal waiting for workflow quorum.
Created on the first apply call for a sandbox with an active
quorum approval workflow, and deleted once the proposal reaches
a terminal state (quorum met, rejected, or superseded by a new
YAML body). Lets subsequent vote-only calls reference the same
proposal by its synthetic chunk_id without requiring the
second runner to resubmit the YAML body — useful when the
second voter is a human on the UI rather than the same CI
pipeline.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
gateway_name |
Mapped[str]
|
Gateway the sandbox belongs to. |
sandbox_name |
Mapped[str]
|
Sandbox the apply targets. |
chunk_id |
Mapped[str]
|
Synthetic chunk id |
yaml_text |
Mapped[str]
|
Raw YAML document body. |
expected_hash |
Mapped[str | None]
|
Optimistic-lock etag captured at proposal time. |
proposed_by |
Mapped[str]
|
Identity of the actor that opened the proposal. |
proposed_at |
Mapped[datetime]
|
When the proposal was created. |
SBOMSnapshot ¶
Bases: Base
A CycloneDX SBOM uploaded for a sandbox.
One snapshot per (gateway, sandbox) pair — a new upload
replaces the previous snapshot rather than appending. Historical
snapshots are intentionally out of scope; if you need them,
archive the raw CycloneDX in object storage from CI before
uploading, because the raw_json column reflects only the
latest upload.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
gateway_name |
Mapped[str]
|
Gateway the sandbox belongs to. |
sandbox_name |
Mapped[str]
|
Sandbox the SBOM describes. |
bom_format |
Mapped[str]
|
CycloneDX-only for now ("CycloneDX"). |
spec_version |
Mapped[str]
|
CycloneDX spec version (e.g. "1.5"). |
serial_number |
Mapped[str | None]
|
Optional CycloneDX serialNumber URN. |
uploaded_by |
Mapped[str]
|
Identity of the user who uploaded the snapshot. |
uploaded_at |
Mapped[datetime]
|
When the snapshot was uploaded. |
component_count |
Mapped[int]
|
Number of components in the SBOM. |
vulnerability_count |
Mapped[int]
|
Number of vulnerabilities declared in the SBOM. |
max_severity |
Mapped[str | None]
|
Highest severity across all vulnerabilities, or None. |
raw_json |
Mapped[str]
|
The original CycloneDX JSON document, retained for download. |
components |
Mapped[list[SBOMComponent]]
|
Cascade-delete relationship to |
SBOMComponent ¶
Bases: Base
A single component row denormalised from a CycloneDX SBOM.
Components are stored as flat rows so the components search
endpoint can paginate and filter via SQL without re-parsing the
raw CycloneDX JSON on each request. The vuln_count and
max_severity columns are maintained at ingest time by
joining through bom_ref against the document's
vulnerabilities array, so the search endpoint never has to
open the raw document.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
snapshot_id |
Mapped[int]
|
Foreign key to the parent SBOM snapshot. |
bom_ref |
Mapped[str | None]
|
CycloneDX bom-ref of the component (used to join vulns). |
name |
Mapped[str]
|
Component name (e.g. "requests"). |
version |
Mapped[str | None]
|
Component version (e.g. "2.31.0"). |
purl |
Mapped[str | None]
|
Package URL (e.g. "pkg:pypi/requests@2.31.0"). |
type |
Mapped[str | None]
|
CycloneDX type (library, framework, container, ...). |
licenses |
Mapped[str | None]
|
Comma-joined license identifiers. |
vuln_count |
Mapped[int]
|
Number of vulnerabilities affecting this component. |
max_severity |
Mapped[str | None]
|
Highest severity across the component's vulnerabilities. |
snapshot |
Mapped[SBOMSnapshot]
|
Backref to the parent |
SandboxBootHook ¶
Bases: Base
A pre- or post-create boot hook attached to a sandbox.
Pre-create hooks act as ShoreGuard-side validation gates: their
commands execute via subprocess.run inside the ShoreGuard
process before CreateSandbox reaches the gateway, with a
whitelisted environment exposing only SG_SANDBOX_NAME,
SG_SANDBOX_IMAGE, SG_SANDBOX_POLICY_ID, and the hook's
user-defined env entries.
Post-create hooks run inside the new sandbox via the existing
ExecSandbox RPC once creation succeeds, intended for warm-up
tasks like package updates or telemetry initialisation.
The execution surface is deliberately on the ShoreGuard side
because the upstream gRPC contract has no native hook RPC. Once
one exists, BootHookService can detect it and delegate
without the schema changing.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[int]
|
Auto-incremented primary key. |
gateway_name |
Mapped[str]
|
Gateway the sandbox belongs to. |
sandbox_name |
Mapped[str]
|
Sandbox this hook attaches to. |
name |
Mapped[str]
|
Human-readable hook name (unique per sandbox+phase). |
phase |
Mapped[str]
|
|
command |
Mapped[str]
|
Shell command to execute (parsed via shlex). |
workdir |
Mapped[str]
|
Working directory inside the sandbox (post-create only). |
env_json |
Mapped[str]
|
JSON-encoded extra environment variables. |
timeout_seconds |
Mapped[int]
|
Hard wall-clock timeout for the hook. |
order |
Mapped[int]
|
Sort key within (sandbox, phase). |
enabled |
Mapped[bool]
|
Whether the hook participates in automatic runs. |
continue_on_failure |
Mapped[bool]
|
If true, post-create failures don't abort subsequent hooks (pre-create always aborts on failure). |
created_by |
Mapped[str]
|
Identity of the user who created the hook. |
created_at |
Mapped[datetime]
|
Timestamp when the hook was created. |
updated_at |
Mapped[datetime]
|
Timestamp of the last update. |
last_run_at |
Mapped[datetime | None]
|
Timestamp of the most recent run. |
last_status |
Mapped[str | None]
|
|
last_output |
Mapped[str | None]
|
Captured stdout+stderr (truncated to 4 KiB). |
OperationRecord ¶
Bases: Base
A tracked long-running operation with DB persistence.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
Mapped[str]
|
UUID primary key. |
status |
Mapped[str]
|
Lifecycle state (pending → running → succeeded/failed, or cancelling → failed). |
resource_type |
Mapped[str]
|
Type of resource (sandbox, exec, gateway). |
resource_key |
Mapped[str]
|
Resource identifier for duplicate detection. |
idempotency_key |
Mapped[str | None]
|
Optional client-provided key for idempotent requests. |
progress_pct |
Mapped[int]
|
Progress percentage (0-100). |
progress_msg |
Mapped[str | None]
|
Human-readable progress message. |
result_json |
Mapped[str | None]
|
JSON-encoded result payload on success. |
error_message |
Mapped[str | None]
|
Error description on failure. |
error_code |
Mapped[str | None]
|
Machine-readable error code (timeout, cancelled, etc.). |
actor |
Mapped[str | None]
|
Identity of the user who started the operation. |
gateway_name |
Mapped[str | None]
|
Gateway the operation targets. |
created_at |
Mapped[datetime]
|
When the operation was created. |
updated_at |
Mapped[datetime]
|
When the operation was last updated. |
completed_at |
Mapped[datetime | None]
|
When the operation finished. |
db ¶
Database engine, session factory, and embedded Alembic migrations.
init_db ¶
Create the engine, run migrations, and configure the session factory.
Called once during application startup (FastAPI lifespan).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str | None
|
SQLAlchemy database URL. Falls back to |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Engine |
Engine
|
The initialised SQLAlchemy engine. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If database migration fails. |
get_engine ¶
Return the current engine.
Returns:
| Name | Type | Description |
|---|---|---|
Engine |
Engine
|
The active SQLAlchemy engine. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If |
init_async_db ¶
Create an async engine matching the sync database URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sync_url
|
str
|
The synchronous SQLAlchemy URL used by :func: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
AsyncEngine |
AsyncEngine
|
The initialised async engine. |
dispose_async_engine
async
¶
Dispose the async engine and clear the session factory.
get_async_session_factory ¶
Return the async session factory.
Returns:
| Name | Type | Description |
|---|---|---|
async_sessionmaker |
async_sessionmaker
|
The active async session factory. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If |