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
6 changes: 3 additions & 3 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -469,14 +469,14 @@
"filename": "internal/server/api/server.gen.go",
"hashed_secret": "9fd0aaae1a3d0bc789d081307161ea9a821f9dee",
"is_verified": false,
"line_number": 3999
"line_number": 4089
},
{
"type": "Secret Keyword",
"filename": "internal/server/api/server.gen.go",
"hashed_secret": "eca525ee60b3564d9633eb140726685271d52341",
"is_verified": false,
"line_number": 4137
"line_number": 4227
}
],
"internal/server/api_scans_test.go": [
Expand Down Expand Up @@ -674,5 +674,5 @@
}
]
},
"generated_at": "2026-07-28T01:05:36Z"
"generated_at": "2026-07-30T02:56:38Z"
}
55 changes: 55 additions & 0 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,30 @@ paths:
application/json:
schema: {$ref: '#/components/schemas/ErrorEnvelope'}

/api/v1/capabilities:
get:
operationId: getCapabilities
summary: What this deployment is entitled to use
description: |
The paywall, made visible. Returns every registered capability with
whether THIS deployment can use it, so the interface can lock or
upsell a control instead of letting a Community user click it and
collect a 402.

Deliberately unauthenticated, like GET /license: a pre-login screen
needs to know what the deployment offers. It exposes no customer
identity and no license key material, only capability ids, their tier,
and whether each is available here.

There are no quotas. Tiering is by capability alone: OpenWatch does not
cap hosts, scans, or users.
responses:
'200':
description: Capability set for this deployment
content:
application/json:
schema: {$ref: '#/components/schemas/CapabilitiesResponse'}

/api/v1/license:
get:
operationId: getLicense
Expand Down Expand Up @@ -2680,6 +2704,10 @@ paths:
/api/v1/reports:generate:
post:
operationId: postReportGenerate
# Gated on the REQUEST, not the route: only report kind `attestation`
# requires the entitlement. The rest of this route is free, so a
# route-level x-required-feature would be a false claim.
x-conditional-feature: compliance_attestation
summary: Generate a Fleet Compliance Executive Summary
description: |
Computes a point-in-time posture snapshot from current data
Expand Down Expand Up @@ -2767,6 +2795,10 @@ paths:
schema: {$ref: '#/components/schemas/ErrorEnvelope'}
post:
operationId: createReportSchedule
# Gated on the REQUEST, not the route: only report kind `attestation`
# requires the entitlement. The rest of this route is free, so a
# route-level x-required-feature would be a false claim.
x-conditional-feature: compliance_attestation
summary: Create a report delivery schedule
description: |
Schedules a report to generate on a daily/weekly/monthly cadence and
Expand Down Expand Up @@ -2934,6 +2966,10 @@ paths:
/api/v1/reports/{id}/export:
get:
operationId: getReportExport
# Gated on the REQUEST, not the route: only report kind `attestation`
# requires the entitlement. The rest of this route is free, so a
# route-level x-required-feature would be a false claim.
x-conditional-feature: compliance_attestation
summary: Download a rendered face of a report (PDF, JSON, CSV, or OSCAL SAR)
description: |
Streams a rendered face of the report as a downloadable
Expand Down Expand Up @@ -5309,6 +5345,25 @@ components:
correlation_id: {type: string}
audit_event_id: {type: string, format: uuid}

CapabilitiesResponse:
type: object
required: [tier, status, capabilities]
properties:
tier: {type: string, enum: [free, enterprise]}
status: {type: string, enum: [active, grace, expired, no_license, invalid]}
capabilities:
type: array
items: {$ref: '#/components/schemas/Capability'}

Capability:
type: object
required: [id, tier, available, description]
properties:
id: {type: string, description: 'Registry id, e.g. remediation_execution'}
tier: {type: string, enum: [free, enterprise]}
available: {type: boolean, description: 'Whether THIS deployment may use it now'}
description: {type: string}

LicenseStateResponse:
type: object
required: [tier, status, features]
Expand Down
67 changes: 67 additions & 0 deletions frontend/src/api/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,37 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/v1/capabilities": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* What this deployment is entitled to use
* @description The paywall, made visible. Returns every registered capability with
* whether THIS deployment can use it, so the interface can lock or
* upsell a control instead of letting a Community user click it and
* collect a 402.
*
* Deliberately unauthenticated, like GET /license: a pre-login screen
* needs to know what the deployment offers. It exposes no customer
* identity and no license key material, only capability ids, their tier,
* and whether each is available here.
*
* There are no quotas. Tiering is by capability alone: OpenWatch does not
* cap hosts, scans, or users.
*/
get: operations["getCapabilities"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/license": {
parameters: {
query?: never;
Expand Down Expand Up @@ -3449,6 +3480,22 @@ export interface components {
/** Format: uuid */
audit_event_id?: string;
};
CapabilitiesResponse: {
/** @enum {string} */
tier: "free" | "enterprise";
/** @enum {string} */
status: "active" | "grace" | "expired" | "no_license" | "invalid";
capabilities: components["schemas"]["Capability"][];
};
Capability: {
/** @description Registry id, e.g. remediation_execution */
id: string;
/** @enum {string} */
tier: "free" | "enterprise";
/** @description Whether THIS deployment may use it now */
available: boolean;
description: string;
};
LicenseStateResponse: {
/** @enum {string} */
tier: "free" | "enterprise";
Expand Down Expand Up @@ -5035,6 +5082,26 @@ export interface operations {
};
};
};
getCapabilities: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Capability set for this deployment */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["CapabilitiesResponse"];
};
};
};
};
getLicense: {
parameters: {
query?: never;
Expand Down
136 changes: 126 additions & 10 deletions internal/server/api/server.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading