diff --git a/.env.example b/.env.example index 1dbf981..bf0c3df 100644 --- a/.env.example +++ b/.env.example @@ -5,11 +5,14 @@ ISSUER_PUBLIC_JWK_JSON='{"kty":"EC","crv":"P-256","x":"","y":""}' DB_PATH=attestations.sqlite DATABASE_URL="file:./prisma/dev.db" # Supabase aliases for apps/api Postgres (optional) +SUPABASE_URL=https://.supabase.co +SUPABASE_SERVICE_ROLE_KEY=replace-with-server-only-service-role-key SUPABASE_DB_URL=postgresql://postgres.:[password]@aws-0-.pooler.supabase.com:6543/postgres?sslmode=require SUPABASE_POOLER_URL=postgresql://postgres.:[password]@aws-0-.pooler.supabase.com:6543/postgres?sslmode=require SUPABASE_DIRECT_URL=postgresql://postgres:[password]@db..supabase.co:5432/postgres?sslmode=require # Optional helper if using Supabase CLI pooler URL discovery from `supabase/.temp/pooler-url`. SUPABASE_DB_PASSWORD=replace-with-supabase-db-password +SUPABASE_SECRET_KEY=replace-with-server-only-secret-key PORT=3000 # apps/api security controls diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 5794563..efc9e92 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -16,6 +16,68 @@ module.exports = { 'import/order': ['error', { 'newlines-between': 'always' }], '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }] }, + overrides: [ + { + files: [ + 'apps/api/src/server.ts', + 'api/**/*.ts', + 'apps/api/src/lib/**/*.ts', + 'apps/api/src/receiptPdf.ts', + 'apps/api/src/security.ts', + 'apps/api/src/db.ts', + 'apps/api/src/registryLoader.ts' + ], + rules: { + 'no-restricted-imports': ['error', { + paths: [ + { + name: './services/registryAdapters.js', + message: 'Gateway code must use ./registry/catalog.js for public registry types and the verification engine interface for registry operations.' + }, + { + name: './services/compliance.js', + message: 'Compliance evaluation is engine-owned. Route code must call the verification engine interface.' + }, + { + name: './anchor.js', + message: 'Anchoring is engine-owned. Route code must call the verification engine interface.' + }, + { + name: './engine/registry/adapterService.js', + message: 'Registry adapter orchestration is engine-owned. Route code must call the verification engine interface.' + }, + { + name: './engine/compliance/cookCountyComplianceValidator.js', + message: 'Compliance evaluation is engine-owned. Route code must call the verification engine interface.' + }, + { + name: './engine/anchoring/service.js', + message: 'Anchoring is engine-owned. Route code must call the verification engine interface.' + } + ], + patterns: [ + { + group: [ + '**/packages/engine-internal/**', + '**/packages/core/src/**', + '**/packages/core/dist/**', + '**/src/core/**', + '**/src/verifiers/**', + '**/src/services/polygonMumbaiAnchor.js', + '**/engine/anchoring/**', + '**/engine/compliance/**', + '**/engine/registry/**', + '**/services/compliance.js', + '**/services/registryAdapters.js', + '**/anchor.js' + ], + message: 'Gateway-facing code must use public contracts and the narrow verification engine interface only.' + } + ] + }] + } + } + ], ignorePatterns: [ '**/node_modules/**', '**/.next/**', diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 69def6f..356dd9b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,19 +1,53 @@ version: 2 + updates: - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" + day: "monday" + time: "05:00" + timezone: "America/Chicago" open-pull-requests-limit: 5 + groups: + npm-production: + dependency-type: "production" + npm-development: + dependency-type: "development" labels: - "dependencies" - "security" + commit-message: + prefix: "deps" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" + day: "monday" + time: "05:30" + timezone: "America/Chicago" open-pull-requests-limit: 5 + groups: + github-actions: + patterns: + - "*" + labels: + - "dependencies" + - "security" + commit-message: + prefix: "deps" + + - package-ecosystem: "cargo" + directory: "/circuits/non_mem_gadget" + schedule: + interval: "weekly" + day: "monday" + time: "06:00" + timezone: "America/Chicago" + open-pull-requests-limit: 3 labels: - "dependencies" - "security" + commit-message: + prefix: "deps" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6dfd96c..1295968 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,14 +1,33 @@ ## Summary -- Describe the change +- Describe the change and why it is needed. -## AI Disclosure +## Change Type -- [ ] AI-assisted changes are included in this PR +- [ ] Runtime or API behavior +- [ ] Security or repo governance +- [ ] Workflow or CI configuration +- [ ] Documentation or claims boundary only +- [ ] Dependency update -## Review Checklist +## Security Review -- [ ] Human review requested -- [ ] Tests added or updated where appropriate +- [ ] Security impact is described - [ ] No secrets, tokens, cookies, or raw PII were added to code, logs, fixtures, or docs -- [ ] Security impact and remaining risks are described +- [ ] New permissions, auth assumptions, or trust-boundary changes are called out +- [ ] Dependency changes were reviewed for risk + +## Claims Boundary And Docs + +- [ ] Public-facing claims or evaluator docs were updated if needed +- [ ] No unsupported claims were introduced + +## Validation + +- [ ] Human review requested +- [ ] Tests or validation commands were run where appropriate +- [ ] Workflow changes were reviewed for least privilege and pinned actions + +## AI Disclosure + +- [ ] AI-assisted changes are included in this PR diff --git a/.github/workflows/contracts-ci.yml b/.github/workflows/contracts-ci.yml new file mode 100644 index 0000000..f00ec7a --- /dev/null +++ b/.github/workflows/contracts-ci.yml @@ -0,0 +1,33 @@ +name: TrustSignal Contracts CI + +on: + pull_request: + paths: + - "packages/contracts/**" + - ".github/workflows/contracts-ci.yml" + push: + branches: + - work + - master + paths: + - "packages/contracts/**" + - ".github/workflows/contracts-ci.yml" + +jobs: + contracts-build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Compile contracts + run: npm run build:contracts diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..f52db3f --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,17 @@ +name: Security / Dependency Review + +on: + pull_request: + +permissions: + contents: read + +jobs: + dependency-review: + name: Dependency diff review + runs-on: ubuntu-latest + steps: + - name: Dependency review + uses: actions/dependency-review-action@v4 # GitHub-maintained action pinned to supported major; Dependabot tracks updates. + with: + fail-on-severity: high diff --git a/.github/workflows/messaging-guardrails.yml b/.github/workflows/messaging-guardrails.yml new file mode 100644 index 0000000..e44e500 --- /dev/null +++ b/.github/workflows/messaging-guardrails.yml @@ -0,0 +1,26 @@ +name: TrustSignal Messaging Guardrails + +on: + pull_request: + paths: + - "README.md" + - "USER_MANUAL.md" + - "docs/**" + - "apps/web/**" + - "package.json" + - "scripts/check-public-messaging.sh" + +jobs: + messaging-check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 22 + + - name: Run messaging guardrail check + run: npm run messaging:check diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 029fd4f..dff814d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,78 +1,44 @@ -# This workflow uses actions that are not certified by GitHub. They are provided -# by a third-party and are governed by separate terms of service, privacy -# policy, and support documentation. +name: Security / OpenSSF Scorecard -name: Scorecard supply-chain security on: - # For Branch-Protection check. Only the default branch is supported. See - # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection - branch_protection_rule: - # To guarantee Maintained check is occasionally updated. See - # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained - schedule: - - cron: '36 3 * * 1' push: - branches: [ "master" ] + branches: + - main + schedule: + - cron: "23 4 * * 1" -# Declare default permissions as read only. -permissions: read-all +permissions: {} jobs: - analysis: - name: Scorecard analysis + scorecard: + name: OpenSSF Scorecard analysis runs-on: ubuntu-latest - # `publish_results: true` only works when run from the default branch. conditional can be removed if disabled. - if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request' permissions: - # Needed to upload the results to code-scanning dashboard. - security-events: write - # Needed to publish results and get a badge (see publish_results below). + actions: read + contents: read id-token: write - # Uncomment the permissions below if installing in a private repository. - # contents: read - # actions: read - + security-events: write steps: - - name: "Checkout code" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v4.1.7 with: persist-credentials: false - - name: "Run analysis" - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 + - name: Run OpenSSF Scorecard + uses: ossf/scorecard-action@v2.4.3 with: - results_file: results.sarif + results_file: scorecard-results.sarif results_format: sarif - # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: - # - you want to enable the Branch-Protection check on a *public* repository, or - # - you are installing Scorecard on a *private* repository - # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. - # repo_token: ${{ secrets.SCORECARD_TOKEN }} - - # Public repositories: - # - Publish results to OpenSSF REST API for easy access by consumers - # - Allows the repository to include the Scorecard badge. - # - See https://github.com/ossf/scorecard-action#publishing-results. - # For private repositories: - # - `publish_results` will always be set to `false`, regardless - # of the value entered here. publish_results: true - # (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore - # file_mode: git - - # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF - # format to the repository Actions tab. - - name: "Upload artifact" - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 + - name: Upload Scorecard SARIF + uses: github/codeql-action/upload-sarif@v4 # GitHub-maintained action pinned to supported major; Dependabot tracks updates. with: - name: SARIF file - path: results.sarif - retention-days: 5 + sarif_file: scorecard-results.sarif - # Upload the results to GitHub's code scanning dashboard (optional). - # Commenting out will disable upload of results to your repo's Code Scanning dashboard - - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@v3 + - name: Upload Scorecard artifact + uses: actions/upload-artifact@v4 # GitHub-maintained action pinned to supported major; Dependabot tracks updates. with: - sarif_file: results.sarif + name: scorecard-results + path: scorecard-results.sarif + retention-days: 7 diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 0000000..26e6709 --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,54 @@ +name: Security / Trivy Filesystem Scan + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + security-events: write + +jobs: + trivy-fs: + name: Trivy repository scan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v4.1.7 + with: + persist-credentials: false + + - name: Run Trivy filesystem scan + uses: aquasecurity/trivy-action@0.34.0 + with: + scan-type: fs + scan-ref: . + scanners: vuln + vuln-type: os,library + severity: HIGH,CRITICAL + ignore-unfixed: true + hide-progress: true + format: sarif + output: trivy-results.sarif + limit-severities-for-sarif: true + exit-code: "0" + skip-dirs: node_modules,.next,dist,coverage,.git + + - name: Upload Trivy SARIF + if: always() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) + uses: github/codeql-action/upload-sarif@v4 # GitHub-maintained action pinned to supported major; Dependabot tracks updates. + with: + sarif_file: trivy-results.sarif + + - name: Summarize Trivy mode + if: always() + run: | + { + echo "## Trivy filesystem scan" + echo "" + echo "- Mode: advisory" + echo "- Scope: filesystem vulnerability scan with HIGH/CRITICAL severity only" + echo "- Notes: ignores unfixed issues and uploads SARIF for review in Security/code scanning when token permissions allow it" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000..10676f0 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,42 @@ +name: Security / zizmor Workflow Audit + +on: + pull_request: + paths: + - ".github/workflows/**" + push: + paths: + - ".github/workflows/**" + +permissions: {} + +jobs: + zizmor: + name: zizmor advisory audit + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + steps: + - name: Checkout + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v4.1.7 + with: + persist-credentials: false + + - name: Run zizmor + continue-on-error: true + uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0 + with: + advanced-security: false + annotations: true + + - name: Summarize zizmor mode + if: always() + run: | + { + echo "## zizmor workflow audit" + echo "" + echo "- Mode: advisory" + echo "- Scope: GitHub Actions workflow security linting" + echo "- Notes: findings are annotated in the run and should be reviewed before merging workflow changes" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/apps/api/.env.example b/apps/api/.env.example index c3692b5..cac9b97 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -4,10 +4,6 @@ NOTARY_API_KEY=replace-with-notary-provider-key PROPERTY_API_KEY=replace-with-property-provider-key TRUST_REGISTRY_SOURCE=state-api://il/notary-registry -# Optional fallback used for ATTOM check routes in non-production. -ATTOM_API_KEY=replace-with-attom-key -ATTOM_BASE_URL=https://api.gateway.attomdata.com - # Free registry source overrides (optional). OFAC_SDN_URL=https://www.treasury.gov/ofac/downloads/sdn.csv OFAC_SLS_URL=https://www.treasury.gov/ofac/downloads/non-sdn.csv @@ -40,13 +36,16 @@ RATE_LIMIT_GLOBAL_MAX=600 RATE_LIMIT_API_KEY_MAX=120 # Database (must enforce TLS; include sslmode=require) -DATABASE_URL=postgresql://user:password@host:5432/deedshield?sslmode=require +DATABASE_URL=postgresql://user:password@host:5432/trustsignal?sslmode=require # Supabase aliases (optional if you prefer naming by provider) +SUPABASE_URL=https://.supabase.co +SUPABASE_SERVICE_ROLE_KEY=replace-with-server-only-service-role-key SUPABASE_DB_URL=postgresql://postgres.:[password]@aws-0-.pooler.supabase.com:6543/postgres?sslmode=require SUPABASE_POOLER_URL=postgresql://postgres.:[password]@aws-0-.pooler.supabase.com:6543/postgres?sslmode=require SUPABASE_DIRECT_URL=postgresql://postgres:[password]@db..supabase.co:5432/postgres?sslmode=require # Optional helper if using Supabase CLI pooler URL discovery from `supabase/.temp/pooler-url`. SUPABASE_DB_PASSWORD=replace-with-supabase-db-password +SUPABASE_SECRET_KEY=replace-with-server-only-secret-key # Blockchain Configuration (Sepolia or Local) ANCHOR_REGISTRY_ADDRESS=0x... diff --git a/scripts/api-boundary-baseline.txt b/scripts/api-boundary-baseline.txt new file mode 100644 index 0000000..d52c773 --- /dev/null +++ b/scripts/api-boundary-baseline.txt @@ -0,0 +1,11 @@ +# Baseline violations for scripts/check-api-boundary.sh +# +# Intentionally tracked so guardrails can be introduced without blocking +# unrelated work. Remove entries as the boundary is cleaned up. +apps/api/src/receiptPdf.ts:2:import { Receipt } from '../../../packages/core/dist/index.js'; +apps/api/src/registryLoader.ts:4:import { TrustRegistry, verifyRegistrySignature } from '../../../packages/core/dist/index.js'; +apps/api/src/server.ts:38:} from '../../../packages/core/dist/index.js'; +apps/api/src/server.ts:41:import { anchorReceipt, buildAnchorSubject } from './anchor.js'; +apps/api/src/server.ts:45:import { attomCrossCheck, DeedParsed } from '../../../packages/core/dist/index.js'; +apps/api/src/server.ts:47:import { CookCountyComplianceValidator } from './services/compliance.js'; +apps/api/src/server.ts:53:} from './services/registryAdapters.js'; diff --git a/scripts/check-api-boundary.sh b/scripts/check-api-boundary.sh new file mode 100644 index 0000000..0486655 --- /dev/null +++ b/scripts/check-api-boundary.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$REPO_ROOT" + +TARGETS=( + "api" + "apps/api/src/server.ts" + "apps/api/src/lib" + "apps/api/src/receiptPdf.ts" + "apps/api/src/security.ts" + "apps/api/src/db.ts" + "apps/api/src/registryLoader.ts" +) + +PATTERN="from ['\"][^'\"]*(packages/engine-internal/|packages/core/(src|dist)/|src/core/|src/verifiers/|src/services/polygonMumbaiAnchor\\.js|/engine/(anchoring|compliance|registry)/|/services/(compliance|registryAdapters)\\.js|/anchor\\.js)[^'\"]*['\"]" + +BASELINE_FILE="${API_BOUNDARY_BASELINE_FILE:-$REPO_ROOT/scripts/api-boundary-baseline.txt}" + +violations="$(rg -n --glob '*.ts' "$PATTERN" "${TARGETS[@]}" | sort || true)" + +if [[ -z "$violations" ]]; then + echo "Public API boundary check passed." + exit 0 +fi + +if [[ ! -f "$BASELINE_FILE" ]]; then + echo "Public gateway boundary violations detected (no baseline file at $BASELINE_FILE):" + echo "$violations" + exit 1 +fi + +baseline="$(rg -v '^(#|\\s*$)' "$BASELINE_FILE" | sort || true)" +new_violations="$(comm -13 <(printf '%s\n' "$baseline") <(printf '%s\n' "$violations") || true)" + +if [[ -n "$new_violations" ]]; then + echo "Public gateway boundary violations detected (not in baseline):" + echo "$new_violations" + exit 1 +fi + +echo "Public API boundary check passed (baseline-only violations present)." diff --git a/scripts/check-public-messaging.sh b/scripts/check-public-messaging.sh new file mode 100644 index 0000000..4754f35 --- /dev/null +++ b/scripts/check-public-messaging.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +FILES=( + "$ROOT/README.md" + "$ROOT/USER_MANUAL.md" + "$ROOT/apps/web/src/app" +) + +BASELINE_FILE="${PUBLIC_MESSAGING_BASELINE_FILE:-$ROOT/scripts/public-messaging-baseline.txt}" + +PATTERNS=( + "production-ready" + "zero-knowledge verification" + "AI fraud scoring" + "universal verification engine" + "cryptographic fraud prevention platform" +) + +echo "Checking public-facing TrustSignal messaging for risky terms..." + +matches="$( + for pattern in "${PATTERNS[@]}"; do + rg -n -i --glob '!**/*.tsbuildinfo' --glob '!**/node_modules/**' "$pattern" "${FILES[@]}" \ + | sed "s/^/[pattern:$pattern] /" || true + done + + rg -n -i --glob '!**/*.tsbuildinfo' --glob '!**/node_modules/**' \ + "DeedShield is an automated document verification platform|Cryptographic Fraud Prevention Platform|AI-first|blockchain-first" \ + "${FILES[@]}" | sed 's/^/[positioning] /' || true + + rg -n -i --glob '!**/*.tsbuildinfo' --glob '!**/node_modules/**' \ + "HIPAA|SOC 2|GDPR" "$ROOT/apps/web/src/app" "$ROOT/USER_MANUAL.md" | sed 's/^/[compliance] /' || true +)" + +matches="$(printf '%s\n' "$matches" | sed "s|$ROOT/||g" | rg -v '^\\s*$' | sort || true)" + +if [[ -z "$matches" ]]; then + echo "Messaging guardrail check passed." + exit 0 +fi + +if [[ ! -f "$BASELINE_FILE" ]]; then + echo + echo "Found flagged messaging (no baseline file at $BASELINE_FILE):" + echo "$matches" + exit 1 +fi + +baseline="$(rg -v '^(#|\\s*$)' "$BASELINE_FILE" | sort || true)" +new_matches="$(comm -13 <(printf '%s\n' "$baseline") <(printf '%s\n' "$matches") || true)" + +if [[ -n "$new_matches" ]]; then + echo + echo "Found flagged messaging (not in baseline):" + echo "$new_matches" + exit 1 +fi + +echo "Messaging guardrail check passed (baseline-only matches present)." diff --git a/scripts/public-messaging-baseline.txt b/scripts/public-messaging-baseline.txt new file mode 100644 index 0000000..0551c8e --- /dev/null +++ b/scripts/public-messaging-baseline.txt @@ -0,0 +1,13 @@ +# Baseline matches for scripts/check-public-messaging.sh +# +# Intentionally tracked so the messaging guardrail can be introduced without +# blocking unrelated work. Remove entries as messaging is tightened. +[pattern:AI fraud scoring] apps/web/src/app/page.tsx:9: 'AI fraud scoring with verifiable machine learning (ezkl) - not a black box', +[pattern:cryptographic fraud prevention platform] apps/web/src/app/layout.tsx:11: title: 'TrustSignal | Cryptographic Fraud Prevention Platform', +[pattern:cryptographic fraud prevention platform] apps/web/src/app/page.tsx:78: © 2026 TrustSignal. All Rights Reserved. Proprietary cryptographic fraud prevention platform. +[pattern:zero-knowledge verification] apps/web/src/app/layout.tsx:13: 'TrustSignal prevents fraud in deeds, licenses, and credentials with zero-knowledge verification and tamper-evident proof anchoring.' +[pattern:zero-knowledge verification] apps/web/src/app/page.tsx:66: Stop fraudulent deeds, licenses, and credentials before they're recorded. Zero-knowledge verification +[pattern:zero-knowledge verification] apps/web/src/app/security/page.tsx:6: TrustSignal applies zero-knowledge verification, signed receipts, revocation controls, and immutable proof +[positioning] USER_MANUAL.md:7:DeedShield is an automated document verification platform designed to prevent real estate title fraud. It protects homeowners and county clerks by ensuring: +[positioning] apps/web/src/app/layout.tsx:11: title: 'TrustSignal | Cryptographic Fraud Prevention Platform', +[positioning] apps/web/src/app/page.tsx:78: © 2026 TrustSignal. All Rights Reserved. Proprietary cryptographic fraud prevention platform. diff --git a/vercel.api.json b/vercel.api.json deleted file mode 100644 index 332dc69..0000000 --- a/vercel.api.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "https://openapi.vercel.sh/vercel.json", - "version": 2, - "buildCommand": "npm --workspace packages/core run build && npm --workspace apps/api run build", - "builds": [ - { - "src": "api/[...path].ts", - "use": "@vercel/node" - } - ], - "routes": [ - { - "src": "/api/(.*)", - "dest": "api/[...path].ts" - } - ], - "headers": [ - { - "source": "/(.*)", - "headers": [ - { - "key": "X-Frame-Options", - "value": "DENY" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - }, - { - "key": "Referrer-Policy", - "value": "strict-origin-when-cross-origin" - }, - { - "key": "Permissions-Policy", - "value": "camera=(), microphone=(), geolocation=()" - }, - { - "key": "Strict-Transport-Security", - "value": "max-age=31536000; includeSubDomains; preload" - } - ] - } - ] -} diff --git a/vercel.json b/vercel.json index 14c7c36..72ec604 100644 --- a/vercel.json +++ b/vercel.json @@ -16,6 +16,18 @@ { "src": "/api/(.*)", "dest": "api/[...path].ts" + }, + { + "src": "/v1/(.*)", + "dest": "api/[...path].ts" + }, + { + "src": "/version", + "dest": "api/[...path].ts" + }, + { + "src": "/health", + "dest": "api/[...path].ts" } ], "headers": [