> ## Documentation Index
> Fetch the complete documentation index at: https://docs.manthan.systems/llms.txt
> Use this file to discover all available pages before exploring further.

# @parmanasystems/server

> Ready-to-deploy Fastify governance server

A ready-to-deploy Fastify HTTP server that exposes the governance runtime as an HTTP API. Use this when you want to run governance as a standalone service rather than embedding it in your application.

## Install

```bash theme={null}
npm install @parmanasystems/server
```

## Starting the server

The server is started by running the package entry point. Configure it via environment variables:

| Variable                   | Description                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------- |
| `PORT`                     | Port to listen on (default: `3000`)                                                |
| `HOST`                     | Host to bind to (default: `0.0.0.0`)                                               |
| `PARMANA_API_KEY`          | Bearer token for authentication (omit for dev mode)                                |
| `PARMANA_SIGNING_KEY`      | PEM-encoded Ed25519 private key (env mode)                                         |
| `PARMANA_SIGNING_KEY_PATH` | Path to PEM key file (disk mode)                                                   |
| `AUDIT_DATABASE_URL`       | PostgreSQL connection URL (enables audit persistence and `/audit/*` routes)        |
| `CORS_ORIGIN`              | Comma-separated allowed origins, or `*` (default: `localhost:5173,localhost:8080`) |
| `LOG_LEVEL`                | Pino log level (default: `info` in production, `debug` otherwise)                  |

If no signing key is configured the server generates an ephemeral Ed25519 keypair on startup (development only).

## API endpoints

| Method | Path                                | Description                                                               |
| ------ | ----------------------------------- | ------------------------------------------------------------------------- |
| `POST` | `/execute`                          | Verify authority before execution — returns signed `ExecutionAttestation` |
| `POST` | `/verify`                           | Verify an `ExecutionAttestation` signature and provenance                 |
| `POST` | `/evaluate`                         | Dry-run policy evaluation — no attestation, no replay slot                |
| `POST` | `/simulate`                         | Full pipeline simulation — no side effects                                |
| `POST` | `/confirm-execution`                | Confirm a real-world action against an authorization                      |
| `GET`  | `/health`                           | Health check                                                              |
| `GET`  | `/runtime/manifest`                 | Runtime version, hash, and supported schema versions                      |
| `GET`  | `/runtime/capabilities`             | Capability declarations for this runtime instance                         |
| `GET`  | `/audit/decisions`                  | Decision timeline (requires `AUDIT_DATABASE_URL`)                         |
| `GET`  | `/audit/decisions/:executionId`     | Decision detail by execution ID (requires `AUDIT_DATABASE_URL`)           |
| `GET`  | `/audit/stats`                      | Aggregate audit statistics (requires `AUDIT_DATABASE_URL`)                |
| `GET`  | `/audit/security`                   | Security event summary (requires `AUDIT_DATABASE_URL`)                    |
| `GET`  | `/audit/verifications/:executionId` | Verification history for an execution (requires `AUDIT_DATABASE_URL`)     |

## POST /execute

Request:

```json theme={null}
{
  "policyId":      "loan-approval",
  "policyVersion": "1.0.0",
  "signals": {
    "credit_score": 720,
    "loan_amount":  15000
  }
}
```

Response (`ExecutionAttestation`):

```json theme={null}
{
  "executionId":           "88a9db95-5f31-4f0d-84de-28a3ec9e3c83",
  "execution_fingerprint": "43258cff...",
  "policyId":              "loan-approval",
  "policyVersion":         "1.0.0",
  "schemaVersion":         "1.0.0",
  "runtimeVersion":        "1.0.0",
  "runtimeHash":           "4ece5616...",
  "signalsHash":           "43258cff...",
  "decision": {
    "action":            "approve",
    "requires_override": false,
    "reason":            "Credit score meets standard threshold."
  },
  "execution_state": "completed",
  "signature":       "TU6LMv5N..."
}
```

Rate limit: 100 requests/minute.

## POST /verify

Request: the full `ExecutionAttestation` object returned by `/execute`.

Response:

```json theme={null}
{
  "valid": true,
  "checks": {
    "signature_verified":  true,
    "runtime_verified":    true,
    "schema_compatible":   true,
    "bundle_verified":     true,
    "release_verified":    true,
    "trust_root_verified": true,
    "evaluator_verified":  true,
    "governed":            true
  },
  "warnings": [],
  "errors": []
}
```

Rate limit: 200 requests/minute.

## POST /evaluate

Dry-run evaluation — computes what decision would be made without issuing an attestation or consuming a replay slot.

Request:

```json theme={null}
{
  "policyId":      "loan-approval",
  "policyVersion": "1.0.0",
  "signals": { "credit_score": 720, "loan_amount": 15000 }
}
```

Response:

```json theme={null}
{
  "wouldDecide":      "approve",
  "ruleMatched":      "approve-standard",
  "reason":           "Credit score meets standard threshold.",
  "signalsValidated": true
}
```

## POST /simulate

Full pipeline simulation. No attestation produced, no replay slot consumed.

Request: same shape as `/execute`.

Response:

```json theme={null}
{
  "simulation":       true,
  "decision": {
    "action":      "approve",
    "reason":      "Credit score meets standard threshold.",
    "ruleMatched": "approve-standard"
  },
  "signalsValidated":   true,
  "policyLoaded":       true,
  "wouldSign":          true,
  "attestationPreview": {
    "policyId":      "loan-approval",
    "policyVersion": "1.0.0",
    "schemaVersion": "1.0.0",
    "execution_state": "completed",
    "dry_run": true
  }
}
```

## POST /confirm-execution

Verifies that a real-world action matches a prior governance authorization and returns a signed `ExecutionIntegrityProof`.

Request:

```json theme={null}
{
  "attestation": { ... },
  "executedAction": {
    "type":       "LOAN_DISBURSED",
    "payload":    { "amount": 15000, "policyId": "loan-approval" },
    "executedAt": "2024-01-15T10:30:00.000Z",
    "executedBy": "disbursement-service"
  },
  "timeWindowSeconds": 300
}
```

Response (`ExecutionIntegrityProof`):

```json theme={null}
{
  "executionId":     "...",
  "authorizationId": "88a9db95-...",
  "integrityHash":   "...",
  "authorized": {
    "action":        "approve",
    "reason":        "Credit score meets standard threshold.",
    "policyId":      "loan-approval",
    "policyVersion": "1.0.0"
  },
  "executed":    { ... },
  "match":       true,
  "matchDetails": {
    "actionTypeMatch":   true,
    "payloadConsistent": true,
    "withinTimeWindow":  true,
    "timeWindowSeconds": 300
  },
  "signature":   "...",
  "confirmedAt": "2024-01-15T10:30:05.000Z",
  "verified":    true
}
```

Rate limit: 100 requests/minute.

## GET /health

```json theme={null}
{
  "status":           "healthy",
  "runtimeVersion":   "1.0.0",
  "runtimeHash":      "4ece5616...",
  "verification":     "PASS",
  "audit_db":         false,
  "signing_mode":     "env",
  "capabilities":     ["execute", "verify", "replay-protection"],
  "supported_schemaVersions": ["1.0.0"]
}
```

`signing_mode` is one of `"env"` (key from environment variable), `"disk"` (key from file), or `"ephemeral"` (generated at startup).

## GET /runtime/manifest

Returns the active governance runtime manifest.

```json theme={null}
{
  "version":                   "1.0.0",
  "runtimeHash":               "4ece5616...",
  "capabilities":              ["execute", "verify", "audit", "replay-protection", "ed25519-signing"],
  "supported_schemaVersions":  ["1.0.0"],
  "startedAt":                 "2024-01-15T10:00:00.000Z"
}
```

## GET /runtime/capabilities

```json theme={null}
{
  "capabilities": [
    "execute",
    "verify",
    "audit",
    "replay-protection",
    "ed25519-signing",
    "memory-replay-store",
    "redis-replay-store"
  ]
}
```

## Audit routes

All `/audit/*` routes are registered only when `AUDIT_DATABASE_URL` is set. They are rate-limited to 60 requests/minute and require bearer auth if `PARMANA_API_KEY` is set.

| Route                                   | Query params                                                                     |
| --------------------------------------- | -------------------------------------------------------------------------------- |
| `GET /audit/decisions`                  | `limit`, `offset`, `policyId`, `decision` (`approve`/`deny`/`any`), `from`, `to` |
| `GET /audit/decisions/:executionId`     | —                                                                                |
| `GET /audit/stats`                      | —                                                                                |
| `GET /audit/security`                   | `from`, `to`, `limit`                                                            |
| `GET /audit/verifications/:executionId` | —                                                                                |

## Using with the SDK client

Use `@parmanasystems/sdk-client` as the companion HTTP client for this server. It provides typed methods for all endpoints.

## Use Cases

### Deploying a governance sidecar for a loan origination service

An NBFC runs the governance server as a sidecar next to its loan origination service. The origination service sends `POST /execute` with each loan application's signals and receives a signed `ExecutionAttestation`. The sidecar is configured with a persistent signing key via `PARMANA_SIGNING_KEY` and uses `AUDIT_DATABASE_URL` to persist every decision to PostgreSQL for regulatory inspection:

```bash theme={null}
PORT=4000
PARMANA_SIGNING_KEY="$(cat /secrets/parmana-private.pem)"
AUDIT_DATABASE_URL="postgresql://parmana:secret@db:5432/governance"
```

The origination service never touches the attestation — it passes it to the disbursement service which calls `POST /confirm-execution` after funds are transferred.

### Using /evaluate for pre-flight policy checks

Before collecting full KYC documentation, a loan app uses `POST /evaluate` to check whether the applicant's initial signals would qualify under the current policy. No attestation is issued and no replay slot is consumed — the response is a dry-run decision:

```bash theme={null}
curl -X POST http://governance:4000/evaluate \
  -H "Content-Type: application/json" \
  -d '{"policyId":"personal-loan","policyVersion":"1.0.0","signals":{"credit_score":680,"monthly_income":65000,"employed":true,"employment_type":"salaried","blacklisted":false,"loan_amount":300000,"emi_obligations":12000}}'
```

If `wouldDecide` is `"reject"`, the app surfaces a rejection message before the borrower completes the full application — saving time for both parties.

### Audit query for SEBI reporting

A fintech running stock margin governance uses the `/audit/*` routes to pull decision timelines for a SEBI inspection. All routes require `AUDIT_DATABASE_URL`. A bearer token is set via `PARMANA_API_KEY` to restrict access:

```bash theme={null}
# Pull all decisions for the personal-loan policy in January 2024
curl -H "Authorization: Bearer $PARMANA_API_KEY" \
  "http://governance:4000/audit/decisions?policyId=personal-loan&from=2024-01-01&to=2024-02-01&limit=1000"
```

Each record in the response is the original `ExecutionAttestation` — independently verifiable using the public key, without requiring access to the live runtime.

## See also

* [SDK Client](/packages/sdk-client) - typed HTTP client for this server
* [Production Checklist](/guides/production-checklist)
* [API Reference](/reference/api-reference) - full function signatures and types
