-
Notifications
You must be signed in to change notification settings - Fork 0
Database Schema
DataShield uses Prisma 7 with PostgreSQL. The schema lives in
prisma/schema.prisma. All identifiers are CUIDs. Every tenant-owned row
references a Company, and deletes cascade from the company down.
erDiagram
Company ||--o{ User : has
Company ||--o{ Employee : has
Company ||--o{ Alert : has
Company ||--o{ DashboardPreset : has
Company ||--o{ DirectoryConnection : has
Company ||--o{ ApiCredential : has
Company ||--o{ Webhook : has
Company ||--o{ RemediationAction : logs
Company ||--o{ ExposureRegisterEntry : records
Company ||--o{ ReportSchedule : schedules
Company ||--o{ Role : defines
Company ||--o{ AuditLog : records
Company ||--o| SsoProvider : trusts
User }o--o| Role : holds
User ||--o{ Session : opens
User ||--o{ Passkey : registers
User ||--o{ TwoFactor : enrolls
User ||--o{ StepUpGrant : earns
User ||--o| DashboardConfig : owns
User ||--o{ DashboardPreset : authors
Employee ||--o{ BreachRecord : has
Employee ||--o{ Alert : triggers
Breach ||--o{ BreachRecord : appears_in
Breach ||--o{ Alert : triggers
Tenant root. domain is unique. Owns every other tenant-scoped entity; all
relations cascade on delete. Holds the auth policy (allowedAuthMethods,
default [TOTP], and ssoMandatory), plus company-wide settings: riskWeights
(JSON override, see Risk Scoring), remediationEnabled (default false,
see Remediation), the SIEM pull token (siemTokenEnc / siemTokenHint) and
push config (siemPushUrlEnc / siemPushHint / siemPushFormat /
siemPushSince, see SIEM Integration), and the auto-scan cadence
(scanIntervalMinutes / lastScanAt).
email unique. Points at an optional Role (roleId, set to null if the role
is deleted). Auth state lives in emailVerified, twoFactorEnabled,
ssoExempt and mustChangePassword. Credentials are held in Account, not on
the user row. Has one optional DashboardConfig, authors many
DashboardPresets, and points to an activePreset (set to null on preset
delete). See Authentication.
A named permission set, scoped to a company. permissions is a String[]
validated against the fixed vocabulary. isSystem marks the built-in
Administrator role, which cannot be edited or deleted; isAssignable controls
whether it can be handed to a user. See Roles and Permissions.
Better Auth's own tables. Session makes sign-ins server-side revocable,
Account holds credentials and linked providers, Verification backs
email and OTP flows.
Per-user TOTP enrollment: secret, backupCodes, verified, plus
failedVerificationCount and lockedUntil for lockout after repeated failures.
A registered WebAuthn credential. A passkey sign-in is complete primary authentication, so the company auth policy is re-checked on that path.
A short-lived proof that the user re-entered their password. Valid for 5 minutes and required before any crown-jewel permission change.
A pending invitation. Only the token hash is stored, and it expires after 72 hours.
One OIDC provider per company. domain plus domainVerified gate whether the
login page routes an email to it. oidcConfig is encrypted at rest through a
Prisma extension.
Append-only record of identity and access changes: action, targetType /
targetId, before / after JSON snapshots, ip, and a nullable
actorUserId so history survives the actor's deletion. See Audit Log.
Fixed-window counters kept in PostgreSQL rather than per-process memory, so limits hold across instances. Expired rows are swept on write.
@@unique([email, companyId]) so the same address can exist across tenants
but is unique within one. Optional department. Optional mfaEnabled
(tri-state: true / false / null unknown, see MFA Coverage). Linked to
BreachRecords and Alerts.
name unique (used as the upsert key by the scan engine). source
(HIBP | MANUAL | DARK_WEB | STEALER_LOG), breachDate, dataTypes
string array.
Join between an Employee and a Breach with the exposedData for that
specific match. @@unique([employeeId, breachId]) prevents duplicate links.
Stealer-log matches add artifacts (ArtifactKind[]) and optional infection
metadata (machineId, malwareFamily, capturedAt). See Breach Scanning.
Severity-scored event. severity (CRITICAL | HIGH | MEDIUM | LOW),
status (OPEN | ACKNOWLEDGED | RESOLVED, defaults OPEN). Employee and
breach references are nullable and set to null on delete so alert history
survives.
An identity-provider connection. type (see DirectoryType),
encryptedConfig (AES-256-GCM blob), status (ACTIVE | ERROR |
PENDING), plus lastSyncAt, lastSyncCount, errorMessage.
A breach-provider API key. provider (see ApiProvider), encryptedKey,
keyHint (display-safe suffix), status, lastUsedAt.
@@unique([companyId, provider]), so one key per provider per company.
A retryable background directory-sync job, tied to a DirectoryConnection.
status (SyncJobStatus), attempts / maxAttempts (default 3), runAfter
for scheduling/backoff, plus startedAt / finishedAt / lastError. See
Directory Integrations.
Outbound notification target. channel (WEBHOOK | SLACK | TEAMS |
EMAIL, defaults WEBHOOK), encryptedUrl (URL or recipient address),
urlHint, minSeverity (defaults MEDIUM), enabled. See Notifications.
Append-only audit of remediation run against the directory. action
(RemediationType), status (SUCCESS | FAILED), target, optional
detail, performedBy, optional employeeId / alertId. See Remediation.
A GDPR exposure record. title, detectedAt, status (RegisterStatus),
affectedCount, dataCategories, optional assessment and notifiedAt.
Deadlines are computed, not stored. See Exposure Register.
A recurring report emailed to recipients. frequency (ScheduleFrequency),
recipients, sections, enabled, lastSentAt. See Reports.
Per-user live layout (DashboardConfig, one per user) and saved presets
(DashboardPreset, scope PERSONAL or COMPANY). Both store layout and
widgets as JSON.
| Enum | Values |
|---|---|
AuthMethod |
TOTP, EMAIL_OTP, PASSKEY
|
Severity |
CRITICAL, HIGH, MEDIUM, LOW
|
AlertStatus |
OPEN, ACKNOWLEDGED, RESOLVED
|
BreachSource |
HIBP, MANUAL, DARK_WEB, STEALER_LOG
|
ArtifactKind |
PASSWORD, COOKIE, TOKEN, AUTOFILL
|
DirectoryType |
AZURE_AD, GOOGLE_WORKSPACE, LDAP, AWS_DIRECTORY, OKTA, SCIM
|
ApiProvider |
HIBP, HIBP_STEALER, DEHASHED, LEAKCHECK, INTELX, SNUSBASE
|
ConnectStatus |
ACTIVE, ERROR, PENDING
|
SyncJobStatus |
PENDING, RUNNING, SUCCEEDED, FAILED
|
PresetScope |
PERSONAL, COMPANY
|
NotificationChannel |
WEBHOOK, SLACK, TEAMS, EMAIL
|
RemediationType |
REVOKE_SESSIONS, FORCE_PASSWORD_RESET
|
RemediationStatus |
SUCCESS, FAILED
|
RegisterStatus |
ASSESSING, NOTIFIED, NOT_REQUIRED
|
ScheduleFrequency |
WEEKLY, MONTHLY
|
Migrations are checked into prisma/migrations/, applied with prisma migrate deploy (npm run db:migrate). The current history:
initadd_dashboard_configadd_preset_scope_and_active_presetadd_directory_connectionsadd_aws_directory_typeadd_okta_scim_directory_typesadd_api_credentialsadd_webhooksadd_sync_jobsadd_schedule_configadd_stealer_log_artifactsadd_notification_channelsadd_company_risk_weightsadd_employee_mfaadd_remediationadd_siem_tokenadd_exposure_registeradd_report_schedulesadd_siem_pushadd_alert_confidenceadd_breach_record_sourcesbetter_authtwo_factor_verification_fieldsadd_passkeyrbac_rolesrbac_audit_stepupadd_rate_limit_tablesadd_sso_provider_and_policyadd_user_invitation_and_forced_password_change
DataShield is source-available software by Melvin PETIT (WhiteMuush). Live demo, read only, no signup.
Getting started
Architecture
Features
- Breach Scanning
- Risk Scoring
- Directory Integrations
- MFA Coverage
- SCIM Provisioning
- Dashboard and Widgets
- Reports
- Exposure Register
Integrations
Identity and access
Reference
Contributing