Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# deepevents.ai
deepevents.ai main codebase

## User & Project Management

- `project-access-audit-anomaly-monitor/` adds a self-contained #11 slice for project audit-log anomaly detection, restricted-access export holds, and owner-review packets.
32 changes: 32 additions & 0 deletions project-access-audit-anomaly-monitor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Project Access Audit Anomaly Monitor

This module is a focused User & Project Management slice for SCIBASE issue #11. It turns project audit logs into deterministic reviewer packets that flag suspicious access patterns before restricted datasets, notebooks, or exports leak outside the intended project boundary.

## What It Adds

- Audit-event scoring for restricted downloads, bulk downloads, data exports, role changes, external invites, API token creation, visibility changes, and object-level permission drift.
- Identity posture checks for MFA, SAML, ORCID, inactive users, and stale external collaborator access windows.
- Object-level permission checks for restricted or embargoed data, download role requirements, restricted licenses, and bulk thresholds.
- Burst detection for rapid role changes or sensitive-download clusters.
- Project-level reviewer packets with owner queues, export-hold decisions, severity counts, JSON output, Markdown output, and SVG preview.

## Why This Is Distinct

Existing #11 submissions cover broad RBAC/workspace ledgers, privacy access reviews, member lifecycle/offboarding, institutional recertification, anonymous review escrow, identity merge/export, data-room consent, researcher profile sync, and project archive handoff. This slice focuses specifically on the project audit log and detects anomalous access behavior after permissions exist.

## Run

```bash
node project-access-audit-anomaly-monitor/test.js
node project-access-audit-anomaly-monitor/demo.js
```

The demo writes:

- `project-access-audit-anomaly-monitor/audit-report.json`
- `project-access-audit-anomaly-monitor/reviewer-packet.md`
- `project-access-audit-anomaly-monitor/demo.svg`

## Decision Policy

Critical events freeze access and open a security review. High events require owner approval before the next sensitive download. Medium events enter the admin queue, while low events are retained for the audit trail.
244 changes: 244 additions & 0 deletions project-access-audit-anomaly-monitor/audit-report.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
{
"generatedAt": "2026-05-20T10:48:48.620Z",
"scoredEvents": [
{
"eventId": "evt:001",
"projectId": "project:neuro-alpha",
"actorId": "user:ext-lee",
"targetUserId": null,
"objectId": "object:patient-counts",
"type": "restricted_download",
"timestamp": "2026-05-20T02:10:00Z",
"score": 100,
"severity": "critical",
"recommendedAction": "freeze_access_and_open_security_review",
"reasons": [
"MFA not enabled",
"ORCID not linked for attribution-sensitive event",
"external collaborator access is expired",
"restricted object touched",
"role reviewer is below required admin",
"new-country access compared with user history",
"after-hours access"
]
},
{
"eventId": "evt:002",
"projectId": "project:neuro-alpha",
"actorId": "user:ext-lee",
"targetUserId": null,
"objectId": "object:patient-counts",
"type": "bulk_download",
"timestamp": "2026-05-20T02:24:00Z",
"score": 100,
"severity": "critical",
"recommendedAction": "freeze_access_and_open_security_review",
"reasons": [
"MFA not enabled",
"external collaborator access is expired",
"restricted object touched",
"role reviewer is below required admin",
"bulk download count 42 exceeds threshold 10",
"after-hours access"
]
},
{
"eventId": "evt:005",
"projectId": "project:materials-sensor",
"actorId": "user:inactive-jo",
"targetUserId": null,
"objectId": "object:sensor-raw",
"type": "data_export",
"timestamp": "2026-05-20T03:30:00Z",
"score": 100,
"severity": "critical",
"recommendedAction": "freeze_access_and_open_security_review",
"reasons": [
"inactive user generated access event",
"embargoed object touched",
"restricted-license object exported"
]
},
{
"eventId": "evt:006",
"projectId": "project:materials-sensor",
"actorId": "user:inactive-jo",
"targetUserId": null,
"objectId": "object:sensor-raw",
"type": "api_token_created",
"timestamp": "2026-05-20T04:00:00Z",
"score": 85,
"severity": "critical",
"recommendedAction": "freeze_access_and_open_security_review",
"reasons": [
"inactive user generated access event",
"embargoed object touched",
"new-country access compared with user history"
]
},
{
"eventId": "evt:004",
"projectId": "project:neuro-alpha",
"actorId": "user:admin-ray",
"targetUserId": null,
"objectId": "object:patient-counts",
"type": "object_permission_drift",
"timestamp": "2026-05-20T03:05:00Z",
"score": 81,
"severity": "high",
"recommendedAction": "require_owner_approval_before_next_download",
"reasons": [
"restricted object touched",
"object permission drift exposes extra roles: reviewer, contributor"
]
},
{
"eventId": "evt:003",
"projectId": "project:neuro-alpha",
"actorId": "user:admin-ray",
"targetUserId": "user:ext-lee",
"objectId": null,
"type": "role_change",
"timestamp": "2026-05-20T02:31:00Z",
"score": 64,
"severity": "medium",
"recommendedAction": "queue_admin_review",
"reasons": [
"unknown object referenced by audit event",
"external collaborator gained contributor-or-higher role",
"role change lacks approval ticket"
]
},
{
"eventId": "evt:007",
"projectId": "project:neuro-alpha",
"actorId": "user:owner-amy",
"targetUserId": null,
"objectId": null,
"type": "project_visibility_change",
"timestamp": "2026-05-20T05:00:00Z",
"score": 30,
"severity": "low",
"recommendedAction": "retain_for_audit",
"reasons": [
"unknown object referenced by audit event"
]
}
],
"projectPackets": [
{
"projectId": "project:neuro-alpha",
"projectTitle": "Neuro Alpha Collaboration",
"institutionId": "inst:western",
"maxScore": 100,
"severityCounts": {
"critical": 2,
"high": 1,
"medium": 1,
"low": 1
},
"holdExport": true,
"ownerQueue": [
{
"eventId": "evt:001",
"severity": "critical",
"action": "freeze_access_and_open_security_review",
"reasons": [
"MFA not enabled",
"ORCID not linked for attribution-sensitive event",
"external collaborator access is expired",
"restricted object touched",
"role reviewer is below required admin",
"new-country access compared with user history",
"after-hours access"
]
},
{
"eventId": "evt:002",
"severity": "critical",
"action": "freeze_access_and_open_security_review",
"reasons": [
"MFA not enabled",
"external collaborator access is expired",
"restricted object touched",
"role reviewer is below required admin",
"bulk download count 42 exceeds threshold 10",
"after-hours access"
]
},
{
"eventId": "evt:004",
"severity": "high",
"action": "require_owner_approval_before_next_download",
"reasons": [
"restricted object touched",
"object permission drift exposes extra roles: reviewer, contributor"
]
}
],
"reviewerSummary": "Restricted access should be frozen until owner/admin review completes."
},
{
"projectId": "project:materials-sensor",
"projectTitle": "Materials Sensor Working Group",
"institutionId": "inst:eastern",
"maxScore": 100,
"severityCounts": {
"critical": 2
},
"holdExport": true,
"ownerQueue": [
{
"eventId": "evt:005",
"severity": "critical",
"action": "freeze_access_and_open_security_review",
"reasons": [
"inactive user generated access event",
"embargoed object touched",
"restricted-license object exported"
]
},
{
"eventId": "evt:006",
"severity": "critical",
"action": "freeze_access_and_open_security_review",
"reasons": [
"inactive user generated access event",
"embargoed object touched",
"new-country access compared with user history"
]
}
],
"reviewerSummary": "Restricted access should be frozen until owner/admin review completes."
}
],
"blockedObjects": [
{
"objectId": "object:patient-counts",
"eventId": "evt:001",
"action": "temporary_export_hold"
},
{
"objectId": "object:patient-counts",
"eventId": "evt:002",
"action": "temporary_export_hold"
},
{
"objectId": "object:sensor-raw",
"eventId": "evt:005",
"action": "temporary_export_hold"
},
{
"objectId": "object:sensor-raw",
"eventId": "evt:006",
"action": "temporary_export_hold"
}
],
"stats": {
"projectCount": 2,
"eventCount": 7,
"criticalCount": 4,
"highCount": 1,
"heldExportCount": 2
}
}
19 changes: 19 additions & 0 deletions project-access-audit-anomaly-monitor/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use strict";

const fs = require("node:fs");
const path = require("node:path");
const {
buildAuditAnomalyMonitor,
buildReviewerMarkdown,
renderAuditSvg
} = require("./index");
const sampleData = require("./sample-data");

const report = buildAuditAnomalyMonitor(sampleData);
const outDir = __dirname;

fs.writeFileSync(path.join(outDir, "audit-report.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(outDir, "reviewer-packet.md"), buildReviewerMarkdown(report));
fs.writeFileSync(path.join(outDir, "demo.svg"), renderAuditSvg(report));

console.log(JSON.stringify(report, null, 2));
Binary file added project-access-audit-anomaly-monitor/demo.mp4
Binary file not shown.
1 change: 1 addition & 0 deletions project-access-audit-anomaly-monitor/demo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading