JSON Schema for CoSec Policies: Structure, Validation, and Examples
CoSec policies are governed by a strict JSON Schema defined in schema/cosec-policy.schema.json that specifies required metadata fields, conditional logic, and action matchers, and can be validated using any Draft-07 compliant validator.
The ahoo-wang/cosec repository implements a composable security framework where access control policies are defined as JSON documents. These documents must conform to a formal schema located in the repository's schema/ directory, ensuring type safety and structural consistency across global, system, and custom policy scopes.
Core Schema Structure
The root policy object requires specific metadata fields and contains the core authorization logic. According to schema/cosec-policy.schema.json, every policy must include category, name, description, tenantId, and type fields, alongside the operational components condition and statements.
The schema declares the JSON-Schema Draft-07 specification ("$schema": "http://json-schema.org/draft-07/schema#"), ensuring compatibility with standard validation libraries and IDE autocomplete features.
Policy Metadata Fields
The metadata section identifies the policy and its scope:
id: Optional unique identifiercategory: Logical grouping (e.g., "security", "example")name: Human-readable identifierdescription: Detailed explanation of policy intenttenantId: Isolation boundary (e.g., "default", "platform")type: Policy scope classification
Policy Types
The type field accepts one of three enumerated values defined in #/definitions/policyType:
global: Applies across all tenants and systemssystem: Bound to specific system contextscustom: User-defined policies with limited scope
Conditions and Statements
CoSec policies implement a two-tier conditional logic structure. The top-level condition acts as a gatekeeper, while individual statements contain granular authorization rules.
Top-Level Conditions
The optional condition field in the policy root must evaluate to true for the policy to be considered. This field references schema/condition.schema.json via $ref, allowing complex boolean logic, authentication checks, or rate limiting to be evaluated before any statements are processed.
If the top-level condition fails, the entire policy is bypassed regardless of statement contents.
Statement Structure
The statements array contains the actual authorization decisions. Each statement object, defined in #/definitions/statement, requires:
action: Required matcher defining which requests apply (referencesschema/action.schema.json)effect: Eitherallowordeny(defaults toallowper#/definitions/effect)condition: Optional statement-level condition for fine-grained controlname: Optional identifier for the statement
Only the action field is mandatory within a statement.
External Schema References
The schema architecture promotes reusability through external references. Rather than embedding all definitions in the main file, CoSec modularizes complex validators into separate schema files.
Condition Schema
Located at schema/condition.schema.json, this file defines all available condition matchers including authenticated, groupedRateLimiter, path-based checks, and boolean composites. Policies reference these definitions via JSON Schema $ref pointers.
Action Schema
The schema/action.schema.json file specifies how to match HTTP requests. Actions can be:
- Simple strings (exact match)
- Arrays of strings (multiple exact matches)
- Complex objects with
path,method, or composite matching rules - Path-based patterns supporting wildcards (e.g.,
/api/**)
Shared Definitions
Common enumerations like effect (allow/deny) and pathOptions reside in schema/definitions.schema.json, preventing duplication across condition and action schemas.
Runtime Validation
The cosec-core/src/main/kotlin/me/ahoo/cosec/policy/PolicyLoader.kt class loads and validates JSON policies against these schemas at runtime. This ensures that only structurally valid policies are activated within the security framework, catching configuration errors during deployment rather than during request processing.
Practical Examples
Minimal Valid Policy
The following policy permits all HTTP GET requests globally:
{
"category": "example",
"name": "AllowAllGet",
"description": "Allows all GET requests for any tenant",
"tenantId": "default",
"type": "global",
"statements": [
{
"action": {
"all": {
"method": "GET"
}
}
}
]
}
This example omits the top-level condition, meaning the policy is always evaluated. The statement defaults to effect: allow and matches any request using the GET method.
Complex Policy with Rate Limiting
This custom policy restricts POST requests to /api/** paths with per-user rate limiting:
{
"category": "security",
"name": "RateLimitedPost",
"description": "Rate-limit POST requests to 10 per second per user",
"tenantId": "platform",
"type": "custom",
"condition": {
"authenticated": {}
},
"statements": [
{
"effect": "allow",
"action": {
"path": {
"pattern": "/api/**",
"method": ["POST"]
}
},
"condition": {
"groupedRateLimiter": {
"part": "context.principal.id",
"permitsPerSecond": 10,
"expireAfterAccessSecond": 60
}
}
}
]
}
Here, the top-level authenticated condition ensures only logged-in users trigger this policy. The statement matches POST methods on /api/** paths and applies a grouped rate limiter keyed by user ID.
Summary
- CoSec policies conform to JSON-Schema Draft-07 defined in
schema/cosec-policy.schema.json - The schema mandates metadata fields (
category,name,tenantId,type) and authorization logic (statements) - Top-level conditions act as policy gates, while statement-level conditions provide granular control
- Action matchers and condition validators are modularized into
action.schema.jsonandcondition.schema.json - Runtime validation occurs via
PolicyLoader.kt, ensuring schema compliance before policy activation
Frequently Asked Questions
What JSON Schema version does CoSec use?
CoSec policies use JSON-Schema Draft-07, as declared in the $schema field of cosec-policy.schema.json. This version ensures broad compatibility with validation tools and libraries while supporting advanced features like $ref references for modular schema design.
Where are the condition and action schemas defined?
Condition matchers are defined in schema/condition.schema.json and action matchers in schema/action.schema.json. The main policy schema references these via $ref pointers, allowing the condition and action logic to be maintained independently while being reused across policy and statement definitions.
Can a policy have multiple statements with different effects?
Yes. A policy's statements array can contain multiple entries, each with independent effect values (allow or deny). CoSec evaluates statements sequentially, and the first matching statement determines the authorization result. This allows creating exceptions to broad allow rules by placing deny statements earlier in the array.
What happens if the top-level condition evaluates to false?
If the policy's top-level condition evaluates to false, the entire policy is bypassed and none of its statements are evaluated. This serves as an efficient gatekeeping mechanism—policies with unsatisfied top-level conditions consume no evaluation resources during request processing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →