Skip to content
gideon-defenderPublic
forked from trycompai/comp
 
 

Latest commit

 

History

8,320 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Logo

Gideon Defender OpenComp

The open-source compliance platform.
Learn more »

Website · Documentation · Issues · Roadmap

Github Stars License Commits-per-month

About

AI that handles compliance for you in hours.

OpenComp is the fastest way to get compliant with SOC 2, ISO 27001, HIPAA, GDPR and other regulatory frameworks. OpenComp automates evidence collection, policy management, and control implementation while keeping you in control of your data and infrastructure.

Built With

Contact us

Contact our team at info@gideondefender.com to learn more about how we can help you achieve compliance.

Stay Up-to-Date

Get access to the cloud hosted version of OpenComp.

Getting Started

To get a local copy up and running, please follow these simple steps.

Prerequisites

Here is what you need to be able to run OpenComp.

  • Node.js (Version: >=22.x)
  • npm (Version: >=10.x)
  • Docker (Version: >=24.x) or Podman (Version: >=5.x)
  • Postgres with PgVector (Version: >=15.x)
  • A Gemini API key (for AI-powered onboarding — free tier works, but has a low daily request cap)

Development

To get the project working locally with all integrations, follow these extended development steps

Setup

Add environment variables and fill them out with your credentials

cp apps/app/.env.example apps/app/.env
cp apps/portal/.env.example apps/portal/.env
cp packages/db/.env.example packages/db/.env

Get code running locally

  1. Clone the repo
git clone https://github.com/gideon-security/opencomp.git
  1. Navigate to the project directory
cd opencomp
  1. Install dependencies using pnpm (v10+, managed via packageManager — corepack activates the pinned version)
pnpm install
  1. Get Database Running
cd packages/db
pnpm run docker:up # Spin up docker container
pnpm run db:migrate # Run migrations
  1. Generate Prisma Types for each app
cd apps/app
pnpm run db:generate
cd ../portal
pnpm run db:generate
cd ../api
pnpm run db:generate
  1. Run all apps in parallel from the root directory
pnpm run dev

Environment Setup

Create the following .env files and fill them out with your credentials

  • opencomp/apps/app/.env
  • opencomp/apps/portal/.env
  • opencomp/apps/api/.env
  • opencomp/packages/db/.env

You can copy from the .env.example files:

Linux / macOS

cp apps/app/.env.example apps/app/.env
cp apps/portal/.env.example apps/portal/.env
cp apps/api/.env.example apps/api/.env
cp packages/db/.env.example packages/db/.env

Windows (Command Prompt)

copy apps\app\.env.example apps\app\.env
copy apps\portal\.env.example apps\portal\.env
copy apps\api\.env.example apps\api\.env
copy packages\db\.env.example packages\db\.env

Windows (PowerShell)

Copy-Item apps\app\.env.example -Destination apps\app\.env
Copy-Item apps\portal\.env.example -Destination apps\portal\.env
Copy-Item apps\api\.env.example -Destination apps\api\.env
Copy-Item packages\db\.env.example -Destination packages\db\.env

Additionally, ensure the following required environment variables are added to .env in opencomp/apps/app/.env:

AUTH_SECRET=""                  # Use `openssl rand -base64 32` to generate
DATABASE_URL="postgresql://user:password@host:port/database"
REDIS_URL="redis://localhost:6379"  # Shared by the kv layer and BullMQ
GOOGLE_GENERATIVE_AI_API_KEY="" # Gemini — powers AI onboarding (https://ai.google.dev/api-keys)
RESEND_API_KEY="" # Resend (https://resend.com/api-keys) - Resend Dashboard -> API Keys
NEXT_PUBLIC_PORTAL_URL="http://localhost:3002"
REVALIDATION_SECRET=""         # Use `openssl rand -base64 32` to generate

✅ Make sure you have all of these variables in your .env file. If you're copying from .env.example, it might be missing the last two (NEXT_PUBLIC_PORTAL_URL and REVALIDATION_SECRET), so be sure to add them manually.

Some environment variables may not load correctly from .env — in such cases, hard-code the values directly in the relevant files (see Hardcoding section below).


Cloud & Auth Configuration

1. Gideon OIDC login

Sign-in is handled by the external Gideon identity provider (OIDC) — there is no per-developer OAuth client setup. Legacy logins (Google/GitHub/Microsoft social, magic link) were removed; their AUTH_* variables no longer exist.

The API needs a Gideon OIDC client registration (ask the auth team for the per-environment client ID). Configure it in opencomp/apps/api/.env (see the documented GIDEON_OIDC_* block in apps/api/.env.example):

GIDEON_OIDC_CLIENT_ID=""     # e.g. opencomp-local (registered with auth team)
GIDEON_OIDC_REDIRECT_URI=""  # e.g. http://localhost:3333/v1/auth/gideon/callback
# GIDEON_OIDC_CLIENT_SECRET="" # only for confidential apps; public apps use PKCE

2. Redis

Redis is configured via the REDIS_URL environment variable (regular Redis — no Upstash required):

REDIS_URL="redis://localhost:6379"

The @gideon-defender/kv package and the local BullMQ trigger runtime both read this variable. Optional hardening: LOCAL_TRIGGER_REDIS_URL points at a full-access (comp_service) Redis role for BullMQ, falling back to REDIS_URL when unset.


Cloud Tests Configuration

Cloud tests collect security posture from AWS, GCP, and Azure. Each cloud connects differently, and OAuth-based clouds (GCP, Azure) need platform-level OAuth app credentials before any connection works.

1. Callback URL

GCP and Azure OAuth both redirect back to the API. Register this URL in each provider's app registration (type Web):

{BASE_URL}/v1/integrations/oauth/callback

(BASE_URL is the API's public URL, e.g. https://api.dev.gideondefender.com in dev, http://localhost:3333 locally.)

2. Per-cloud setup

Cloud Auth What to configure
AWS (aws) IAM role assumption (no OAuth) Nothing platform-wide. Each connection renders its own CloudShell script with a per-connection external ID — run it in the target account.
GCP (gcp) OAuth2 Google Cloud Console → APIs & Services → Credentials → OAuth client ID (Web application), with the callback URL above in Authorized redirect URIs. Actual access is limited by IAM roles — connecting users only need read-only roles like roles/securitycenter.findingsViewer.
Azure (azure) OAuth2 Azure Portal → App registrations → New registration, account type Accounts in any organizational directory (multitenant), with the callback URL above as a Web redirect URI. Then Certificates & secrets → new client secret. Actual access is controlled by Azure RBAC — connecting users need at least Reader (plus Security Reader for Defender for Cloud data).
Azure organizational accounts

Azure OAuth uses Microsoft's /organizations authority for both endpoints:

  • Authorization: https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize
  • Token exchange and refresh: https://login.microsoftonline.com/organizations/oauth2/v2.0/token

This supports Microsoft Entra work or school accounts across organizational directories, not personal Microsoft accounts. Keep the app registration's Supported account types set to Accounts in any organizational directory (multitenant). organizations is Microsoft's account-type selector, not an OpenComp organization ID or a hardcoded Azure tenant ID.

If Microsoft reports unauthorized_client with "not enabled for consumers", restart the connection using a work or school account and verify that the configured client ID is the registration's Application (client) ID. Do not enable personal accounts solely to work around this error. See Microsoft's authority and account-type documentation.

For personal Microsoft identities or guest accounts accessing an Azure directory, set Directory (tenant) ID alongside Client ID and Client Secret in Admin → Integrations → Microsoft Azure (organization or platform settings). Use the directory UUID from Microsoft Entra ID → Overview. OpenComp then uses that directory for authorization and token exchange and pins it to the resulting connection for refresh. This avoids the account chooser loop / AADSTS50059 when Microsoft cannot infer the directory from a personal identity. Blank retains organizations; personal accounts must already have access to the target directory. The API setting is customSettings: { "tenantId": "<directory-uuid>" }.

After changing the OAuth endpoints, rebuild and deploy the OpenComp API, then start a fresh Azure connection flow. The endpoint switch alone does not require new client credentials or a different callback URL.

3. Store the platform credentials

OAuth credentials are read from the database, not env vars — one row per provider (org-level rows take precedence, platform rows are the fallback). Save them via the admin endpoint (same call per provider, different slug and values):

curl -X POST "$BASE_URL/v1/admin/integrations/credentials" \
  -H "Authorization: Bearer <admin-session-or-service-token>" \
  -H "Content-Type: application/json" \
  -d '{"providerSlug": "azure", "clientId": "<app-id>", "clientSecret": "<secret>"}'

Verify with the availability check:

curl "$BASE_URL/v1/integrations/oauth/availability?providerSlug=azure"
# {"available": true, "hasPlatformCredentials": true, ...}

⚠️ No OAuth credentials available for <provider> means neither an org-level nor a platform-level credential row exists for that exact slug (gcp, azure). Creating the GCP row does not cover Azure — repeat step 3 per cloud.


Languages (i18n)

The app ships with English and Spanish locales. The locale is resolved from the NEXT_LOCALE cookie; clear that cookie to fall back to English. All UI strings live in apps/app/messages/en.json and apps/app/messages/es.json — keep both files in sync when adding keys.


Testing

# App unit tests (Vitest)
cd apps/app && pnpm exec vitest run

# API unit tests (Jest) — loads apps/api/.env automatically
cd apps/api && pnpm exec jest --forceExit

# API e2e tests — needs a local Postgres + migrations applied
cd apps/api && pnpm run test:e2e

# App e2e tests (Playwright) — boots the full stack; see .github/workflows/e2e.yml
cd apps/app && pnpm exec playwright test --project=chromium

Database Setup

Start and initialize the PostgreSQL database using Docker:

  1. Start the database:

    cd packages/db
    pnpm run docker:up
  2. Default credentials:

    • Database name: comp
    • Username: postgres
    • Password: postgres
  3. To change the default password:

    ALTER USER postgres WITH PASSWORD 'new_password';
  4. If you encounter the following error:

    HINT: No function matches the given name and argument types...
    

    Run the fix:

    psql "postgresql://postgres:<your_password>@localhost:5432/comp" -f ./packages/db/prisma/functionDefinition.sql

    Expected output: CREATE FUNCTION

    💡 comp is the database name. Make sure to use the correct port and database name for your setup.

  5. Apply schema and seed:

 # Generate Prisma client
 pnpm run db:generate

 # Push the schema to the database
 pnpm run db:push

  # Optional: Seed the database with initial data
  pnpm run db:seed

Other useful database commands:

# Open Prisma Studio to view/edit data
pnpm run db:studio

# Run database migrations
pnpm run db:migrate

# Stop the database container
pnpm run docker:down

# Remove the database container and volume
pnpm run docker:clean

Start Development

Once everything is configured:

pnpm run dev

Or use the Turbo repo script (turbo is a root devDependency, no global install needed):

pnpm exec turbo dev

🎉 Yay! You now have a working local instance of Gideon Defender OpenComp! 🚀

Full Stack with Docker Compose

The monorepo ships a Docker-based local stack that runs everything with node:22 + pnpm. It builds and starts the API, app, and portal along with Postgres, Redis, and LocalStack (AWS S3). Podman works too (alias docker=podman, or podman-compose):

# Build and start the whole stack (app on :3000, portal on :3002, api on :3333)
docker-compose up -d --build

# Run database migrations and seed data
docker-compose run --rm migrator
docker-compose run --rm seeder

# Tail logs for a service (e.g. the app)
docker-compose logs -f app

# Stop everything
docker-compose down

Services: localstack (S3/SES emulation), postgres (pgvector), migrator (Prisma migrate), seeder, api (NestJS), redis, app (Next.js frontend), portal (employee portal), email-worker (SQS email consumer), embeddings (self-hosted BAAI/bge-m3 via Ollama).

💡 Note: each service's container env overrides the matching .env file entries for in-container hostnames (e.g. the portal gets DATABASE_URL=…@postgres:5432 while host-side tooling uses localhost:5432).

Deployment

Docker

Steps to deploy OpenComp on Docker are coming soon.

AWS

Gideon hosted production and dev environments run on AWS

To deploy the main branch to dev, run the Deploy to Dev workflow from the repository's Actions tab. The workflow is restricted to repository administrators, applies database migrations, builds in parallel then pushes the ARM64 API, app, trust-center, and migrator images, and rolls the ECS services. It uses the dev environment secrets AWS_ACCOUNT_ID, AWS_REGION, ECS_CLUSTER, AWS_ROLE_TO_ASSUME, MIGRATOR_SUBNETS and MIGRATOR_SECURITY_GROUP. The employee portal is not currently deployed by this workflow.

Dev domains (*.dev.gideondefender.com): opencomp.dev → app, trust.dev/{friendlyUrl} → trust-center, api.dev → API.

Key env/config for a dev deploy:

BASE_URL=https://api.dev.gideondefender.com
NEXT_PUBLIC_APP_URL=https://opencomp.dev.gideondefender.com
NEXT_PUBLIC_API_URL=https://api.dev.gideondefender.com
NEXT_PUBLIC_TRUST_API_URL=https://trust.dev.gideondefender.com
TRUST_APP_URL=https://trust.dev.gideondefender.com  # build-time for trust-center
LOCAL_TRIGGER_DATABASE_URL=postgresql://...?options=-c%20search_path%3Dopencomp_trigger%2Cpublic

We are not baking secrets into the image!

AWS services used to host OpenComp:

  • Bedrock
  • ECS Fargate
  • ElastiCache
  • RDS Postgres with RLS enabled
  • S3
  • SES
  • SQS

Notes: session cookies are isolated per env (dev prefix / .dev.gideondefender.com domain, mirroring the staging carve-out); opencomp.dev.gideondefender.com must be in the billing-redirect allowlist; leave TRUST_PORTAL_PROJECT_ID / Vercel vars unset in dev (custom domains stay on the shared-domain path until a separate dev Vercel project exists); the deploy workflow runs prisma migrate deploy (including the opencomp_trigger schema) before replacing ECS tasks.

📦 Package Publishing

This repository uses semantic-release to automatically publish packages to npm when merging to the release branch. The following packages are published:

  • @gideon-defender/db - Database utilities with Prisma client
  • @gideon-defender/email - Email templates and components
  • @gideon-defender/kv - Key-value store utilities using Redis
  • @gideon-defender/ui - UI component library with Tailwind CSS

Setup

  1. NPM Token: Add your npm token as NPM_TOKEN in GitHub repository secrets
  2. Release Branch: Create and merge PRs into the release branch to trigger publishing
  3. Versioning: Uses conventional commits for automatic version bumping

Usage

# Install a published package
pnpm add @gideon-defender/ui

# Use in your project
import { Button } from '@gideon-defender/ui/button'
import { client } from '@gideon-defender/kv'

Development

# Build all packages
pnpm run build

# Build specific package
pnpm --filter=@gideon-defender/ui run build

# Test packages locally
pnpm run release:packages -- --dry-run

License

OpenComp is an open-source software, licensed under AGPLv3

Tip

We work closely with the community and always invite feedback about what should be open and what is fine to be commercial. This list is not set and stone and we have moved things from commercial to open in the past. Please open a discussion if you feel like something is wrong.

Releases

Packages

Used by

Contributors

Languages