Skip to content
Merged
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
12 changes: 10 additions & 2 deletions .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ JIRA_HOST=yourorg.atlassian.net
JIRA_EMAIL=service-account@yourorg.com
JIRA_API_TOKEN=your-jira-api-token
JIRA_SECOPS_PROJECT_KEY=SECOPS
# Optional full JQL override. The default finds open issues whose summary contains "User-reported phishing".
# JIRA_PHISHING_JQL=project = "SECOPS" AND labels = phishing-intake AND statusCategory != Done ORDER BY created DESC

# Google Workspace Configuration
GOOGLE_CLIENT_EMAIL=service-account@your-project.iam.gserviceaccount.com
Expand All @@ -17,8 +19,14 @@ VIRUSTOTAL_API_KEY=your-virustotal-api-key
OPENROUTER_API_KEY=your-openrouter-api-key
OPENROUTER_MODEL=anthropic/claude-3.5-sonnet

# Authentication (Future Use)
NEXTAUTH_SECRET=your-nextauth-secret
# SecureCatch access control
# Generate the password hash with: printf '%s' 'a-long-password' | npm run auth:hash-password
SECURECATCH_ADMIN_PASSWORD_HASH=scrypt$16384$8$1$replace-with-salt$replace-with-hash
# Generate a random secret with: openssl rand -base64 48
SECURECATCH_SESSION_SECRET=replace-with-at-least-32-random-characters

# Safety gate. Keep false until authentication is configured and a dry run has been reviewed.
SECURECATCH_ENABLE_DESTRUCTIVE_ACTIONS=false

# Database
DATABASE_URL=file:./dev.db
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
push:
branches: [securecatch-base, main]
pull_request:
branches: [securecatch-base, main]

jobs:
quality:
runs-on: ubuntu-latest
permissions:
contents: read
env:
DATABASE_URL: file:./dev.db
SECURECATCH_SESSION_SECRET: ci-only-session-secret-with-at-least-32-characters
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run build
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<!-- BEGIN:nextjs-agent-rules -->

# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.

<!-- END:nextjs-agent-rules -->
113 changes: 93 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,109 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
# SecureCatch

## Getting Started
SecureCatch is a human-in-the-loop phishing triage console for Google Workspace and Jira. It gathers reported-email evidence, enriches indicators with VirusTotal, asks a configured OpenRouter model for a structured classification, and presents the result for analyst review.

First, run the development server:
Remediation is deliberately gated. A signed administrator session is required for every page and API route, state transitions are claimed atomically, domain-wide deletion is disabled by default, and an analyst must type the Jira ticket key before a purge can begin.

## What it does

1. Ingests open phishing reports from a Jira project.
2. Resolves the corresponding message through Google Workspace Alert Center and Gmail.
3. Extracts headers, message text, sender data, and links.
4. Enriches domains, IPs, and URLs with VirusTotal.
5. Produces a validated `Phishing`, `Spam`, or `Safe` assessment through OpenRouter.
6. Pauses in `AWAITING_REVIEW` for an analyst decision.
7. Optionally trashes the matching RFC 2822 message across Workspace accounts and updates Jira.

The model never acts on its own. Its output is advisory, must match a strict JSON schema, and cannot bypass the review and confirmation controls.

## Safety model

- **Private operator access:** an administrator password creates an eight-hour, HMAC-signed, `HttpOnly`, `SameSite=Strict` session.
- **Protected APIs:** route-level authorization remains in place even if the Next.js proxy is changed accidentally.
- **CSRF resistance:** state-changing endpoints reject requests without a same-origin signal.
- **Fail-closed remediation:** `SECURECATCH_ENABLE_DESTRUCTIVE_ACTIONS` defaults to `false`.
- **Explicit confirmation:** a domain-wide purge requires the exact Jira ticket key.
- **Single-action claims:** an atomic database transition prevents two operators from starting the same action.
- **Untrusted evidence boundaries:** email content and threat-intelligence fields are marked as untrusted in the model prompt.
- **Safe parse failures:** malformed model output is rejected instead of being stored as analysis.

SecureCatch is designed as an internal, single-administrator tool. Put deployed instances behind a private network or identity-aware access proxy as an additional boundary. Review Google Workspace delegation scopes before enabling remediation.

## Stack

- Next.js 16 and React 19
- TypeScript and Tailwind CSS
- Prisma with SQLite for a local or single-instance deployment
- Google Workspace APIs: Gmail, Alert Center, and Admin SDK
- Jira REST API
- VirusTotal API
- OpenRouter-compatible chat completions

## Quick start

Prerequisites: Node.js 20 or newer; npm; and credentials for the integrations you plan to use.

```bash
git clone https://github.com/cjcsecurity/SecureCatch.git
cd SecureCatch
npm ci
cp .env.local.example .env.local
```

Generate the two access-control values and place them in `.env.local`:

```bash
printf '%s' 'choose-a-long-unique-password' | npm run auth:hash-password
openssl rand -base64 48
```

Then initialize and run the app:

```bash
npm run db:migrate
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
Open [http://localhost:3000](http://localhost:3000) and sign in. Keep `SECURECATCH_ENABLE_DESTRUCTIVE_ACTIONS=false` while validating ingestion and analysis with your environment.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
The complete Google Workspace, Jira, and API configuration is in [SETUP.md](SETUP.md).

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## Development checks

## Learn More
```bash
npm run lint
npm run typecheck
npm test
npm run build
```

`npm run check` runs all four. Pull requests run the same checks in GitHub Actions.

To learn more about Next.js, take a look at the following resources:
The tests cover signed-session validation, remediation policy gates, and strict model-response parsing. External services are not contacted during the test suite.

## Workflow states

```text
PENDING -> INGESTED -> ANALYSIS_RUNNING -> AWAITING_REVIEW
| |
ANALYSIS_FAILED +------------------+
| |
CLOSING REMEDIATING
| |
CLOSED REMEDIATED
\ /
+-- ACTION_FAILED
```

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
An `ACTION_FAILED` result means the operator should inspect server logs and verify external-system state before retrying or taking manual action. A failure may occur after an external API has completed part of a multi-step operation.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
## Operational limitations

## Deploy on Vercel
- SQLite is appropriate for local use or one application instance with persistent storage. A multi-instance deployment needs a shared database and a reviewed Prisma migration strategy.
- Domain-wide remediation uses delegated Gmail access and performs one mailbox operation at a time. Test with a constrained Workspace environment first.
- Jira workflow transition IDs vary by project. Confirm the configured transition behavior before using it against production tickets.
- OpenRouter and VirusTotal receive the evidence sent by their respective integration code. Apply your organization’s data-handling rules before connecting real mail.

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
## Security reports

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
Please avoid posting exploitable details in a public issue. Use the repository’s private vulnerability-reporting option under the **Security** tab when available.
Loading
Loading