Skip to content

APIs

Target Architecture — Final-State Design

This page describes the final-state API surface of the Governance, Security & Compliance Platform. All endpoints are OpenIddict-secured (OAuth2/JWT), tenant-scoped, and versioned. REST paths follow the Naming Conventions (plural, hyphenated nouns; verb sub-paths for non-CRUD actions).

API Surface Overview

The platform exposes eight public REST endpoints across the Policy, Approval, Audit, Compliance, and Security contexts. Supplier services (PolicyEvaluationService, TenantIsolationPolicyService, DataClassificationService, RiskScoringService, SecretGovernanceService) expose internal gRPC only.

Method Path Service Purpose
POST /policies PolicyDefinitionService Create/version a policy definition.
POST /policies/evaluate PolicyEngineService Evaluate policy for an action (the inline PDP call).
POST /approvals ApprovalService Raise a human approval request.
POST /approvals/{approvalId}/approve ApprovalService Approve a pending request.
POST /approvals/{approvalId}/reject ApprovalService Reject a pending request.
GET /audit AuditService Query the immutable audit trail.
POST /security-findings SecurityFindingService Ingest/raise a security finding.
POST /compliance/reports ComplianceReportService Generate a compliance report/evidence bundle.

Public vs. Internal vs. gRPC

  • Public REST — the eight endpoints above. Consumed by Factory Studio, the Control Plane, DevOps & GitOps, and external integrators.
  • Internal gRPC — low-latency, inline calls used by PolicyEngineService to consult PolicyEvaluationService, TenantIsolationPolicyService, DataClassificationService, and RiskScoringService; and by the Agent Mesh for permission/prompt-safety checks. Defined via ConnectSoft.Extensions.ServiceModel.Grpc with ConnectSoft.Extensions.Saas.AspNetCore.Grpc tenant interceptors.
  • Events — all state changes also publish the canonical domain events; consumers should prefer the event stream over polling for asynchronous reactions.

Authorization

Concern Mechanism
Authentication OAuth2/JWT bearer tokens issued by OpenIddict. Service-to-service calls use client-credentials tokens.
Coarse authorization RBAC scopes per endpoint, e.g. governance.policy.write, governance.policy.evaluate, governance.approval.decide, governance.audit.read, governance.compliance.generate, governance.security.write.
Fine authorization ABAC: the platform evaluates its own policies (subject attributes, resource classification, tenant, risk) on every write — governance governs itself.
Tenant isolation tenantId claim is asserted against the request scope by ConnectSoft.Extensions.Saas.AspNetCore and ConnectSoft.Extensions.WebSecurity middleware before any handler runs.
Approver separation An approver cannot approve a request they raised (segregation of duties), enforced in ApprovalService.

Versioning

  • URI-independent, header-based versioning: clients send Api-Version: 2026-06-01; the default is the latest stable.
  • Backward-compatible additions (new optional fields) do not bump the version. Breaking changes introduce a new dated version and a deprecation window.
  • Event contracts version independently per the Event Envelope rules (cs-schema-version, ArtifactCreatedV2-style suffixes).

Examples

POST /policies

Create (or version) a policy definition with one or more rules.

{
  "name": "ProductionDeploymentGate",
  "domain": "deployment-gates",
  "description": "Require approval for production deployments of restricted-classified artifacts.",
  "effect": "RequiresApproval",
  "rules": [
    {
      "subject": { "role": "ReleaseAgent" },
      "resource": { "type": "Deployment", "environment": "prod" },
      "action": "Promote",
      "condition": "resource.classification == 'Restricted' || risk.score >= 70",
      "gate": "HumanApproval"
    }
  ]
}

Response 201 Created:

{
  "policyDefinitionId": "pol-7b3c1f9a",
  "name": "ProductionDeploymentGate",
  "version": "3",
  "status": "Published",
  "tenantId": "connectsoft",
  "createdAt": "2026-06-11T09:00:00Z"
}

POST /policies/evaluate

The inline policy decision point call.

{
  "subject": { "agentId": "agent-release-01", "role": "ReleaseAgent" },
  "resource": { "type": "Deployment", "artifactId": "art-api-7c", "classification": "Restricted", "environment": "prod" },
  "action": "Promote",
  "context": { "projectId": "proj-booking-saas", "traceId": "trace-9f1c2b7d", "correlationId": "corr-3a6e1d40" }
}

Response 200 OK:

{
  "decision": "RequiresApproval",
  "policyDecisionId": "dec-4d21ab",
  "matchedPolicy": { "policyDefinitionId": "pol-7b3c1f9a", "version": "3" },
  "riskScore": 82,
  "approvalRequestId": "apr-91c2",
  "reason": "Restricted artifact promotion to prod exceeds risk threshold.",
  "evaluatedAt": "2026-06-11T09:00:01Z"
}

POST /approvals

Raise a human approval request (usually created automatically by PolicyEngineService, but also callable directly).

{
  "subject": { "agentId": "agent-release-01" },
  "action": "Promote",
  "resource": { "type": "Deployment", "artifactId": "art-api-7c", "environment": "prod" },
  "policyDecisionId": "dec-4d21ab",
  "requiredApprovers": ["role:ReleaseManager"],
  "timeoutMinutes": 240,
  "context": { "traceId": "trace-9f1c2b7d", "correlationId": "corr-3a6e1d40" }
}

Response 201 Created:

{
  "approvalId": "apr-91c2",
  "status": "Pending",
  "expiresAt": "2026-06-11T13:00:00Z"
}

POST /approvals/{approvalId}/approve

{
  "approverId": "user-release-manager-7",
  "comment": "Verified change ticket CHG-2291 and rollback plan.",
  "justification": "Scheduled release within maintenance window."
}

Response 200 OK:

{
  "approvalId": "apr-91c2",
  "status": "Approved",
  "decidedAt": "2026-06-11T09:42:00Z",
  "decision": { "approvalDecisionId": "apd-55fa", "outcome": "Granted" }
}

POST /approvals/{approvalId}/reject

{
  "approverId": "user-release-manager-7",
  "comment": "Missing rollback verification.",
  "justification": "Does not meet release readiness checklist."
}

Response 200 OK:

{
  "approvalId": "apr-91c2",
  "status": "Rejected",
  "decidedAt": "2026-06-11T09:45:00Z",
  "decision": { "approvalDecisionId": "apd-55fb", "outcome": "Rejected" }
}

GET /audit

Query the immutable audit trail. Filters are tenant-scoped automatically.

GET /audit?traceId=trace-9f1c2b7d&from=2026-06-11T00:00:00Z&to=2026-06-11T23:59:59Z&action=Promote&page=1&pageSize=50

Response 200 OK:

{
  "page": 1,
  "pageSize": 50,
  "total": 3,
  "items": [
    {
      "auditEntryId": "aud-001",
      "action": "PolicyDecisionRecorded",
      "subject": "agent-release-01",
      "resource": "art-api-7c",
      "outcome": "RequiresApproval",
      "traceId": "trace-9f1c2b7d",
      "hash": "sha256:9a1b...",
      "previousHash": "sha256:00ff...",
      "occurredAt": "2026-06-11T09:00:01Z"
    }
  ]
}

POST /security-findings

Ingest a finding from a scanner or a runtime detector.

{
  "source": "SecretScanWorker",
  "category": "LeakedSecret",
  "severity": "High",
  "resource": { "type": "Artifact", "artifactId": "art-config-3a", "moduleId": "module-reservations-api" },
  "title": "Hard-coded connection string detected",
  "evidence": { "location": "appsettings.json:42", "ruleId": "CS-SECRET-001" },
  "context": { "projectId": "proj-booking-saas", "traceId": "trace-9f1c2b7d" }
}

Response 201 Created:

{
  "securityFindingId": "sf-7710",
  "status": "Open",
  "severity": "High",
  "riskScore": 88,
  "dedupKey": "CS-SECRET-001:art-config-3a:appsettings.json:42"
}

POST /compliance/reports

Generate a point-in-time compliance report / evidence bundle.

{
  "framework": "SOC2",
  "scope": { "tenantId": "connectsoft", "projectId": "proj-booking-saas" },
  "period": { "from": "2026-04-01T00:00:00Z", "to": "2026-06-30T23:59:59Z" },
  "includeEvidence": true
}

Response 202 Accepted:

{
  "complianceReportId": "cr-3320",
  "status": "Generating",
  "framework": "SOC2",
  "evidenceLocation": null,
  "requestedAt": "2026-06-11T09:00:00Z"
}

When the ComplianceReportWorker completes, the report transitions to Generated, ComplianceReportGenerated is published, and evidenceLocation points to the Blob evidence bundle.