Multi-tenant, reactive security for Spring: IAM-style policies and role-based permissions, evaluated deny-first for every request.
- Policies as data. JSON policies with path actions, composable conditions (roles, tenants, headers, IP, expressions) and rate limits. Change them at runtime; every instance sees the change immediately.
- Deny wins, everywhere. Global policies, the principal's own policies and role permissions are combined deny-first, unmatched requests are denied, and errors deny.
- Multi-tenant and role-based. Tenant-aware principals, plus per-application permission catalogs granted to roles per space.
- One pipeline, three stacks. Spring WebFlux, Spring MVC and Spring Cloud Gateway share the same security pipeline and respond identically.
- Fast and reactive. Built on Project Reactor. About 2 µs per decision, with no event-loop blocking.
- Auditable. An audit event (log or Kafka) and an OpenTelemetry span for every decision, naming the policy or permission that decided it.
flowchart LR
R([Request + JWT]) --> ROOT{Root?}
ROOT -->|yes| ALLOW([ALLOW])
ROOT -->|no| L["Global policies<br>Principal policies<br>Role permissions"]
L --> D{Any DENY matched?}
D -->|yes| DENY([EXPLICIT_DENY])
D -->|no| A{Any ALLOW matched?}
A -->|yes| ALLOW
A -->|no| IMP([IMPLICIT_DENY])
Denied anonymous callers get 401, authenticated callers 403, and rate-limited requests 429.
dependencies {
implementation(platform("me.ahoo.cosec:cosec-bom:<version>"))
implementation("me.ahoo.cosec:cosec-spring-boot-starter") {
capabilities { requireCapability("me.ahoo.cosec:webflux-support") } // or webmvc-support / gateway-support
}
implementation("me.ahoo.cosec:cosec-spring-boot-starter") {
capabilities { requireCapability("me.ahoo.cosec:cache-support") } // Redis-backed policy storage
}
}cosec:
jwt:
secret: ${COSEC_JWT_SECRET}
authorization:
local-policy:
enabled: true # classpath:cosec-policy/*-policy.json
init-repository: true{
"id": "app", "name": "App", "category": "app", "description": "", "type": "global", "tenantId": "(platform)",
"statements": [
{ "name": "public", "action": ["/auth/login", "/actuator/health"] },
{ "name": "authenticated", "action": "/api/**", "condition": { "authenticated": {} } },
{ "name": "admins-only", "effect": "deny", "action": "/api/admin/**",
"condition": { "inRole": { "value": "admin", "negate": true } } }
]
}Continue with the Quick Start to issue tokens, then the policy reference.
The starter brings the core, JWT support and auto-configuration; each integration (WebFlux, MVC, Gateway,
Redis, OAuth, OpenTelemetry, OpenAPI, ip2region, Kafka) is an opt-in Gradle capability. See
Modules for the full list. A ready-to-run gateway is
published as the container image ahoowang/cosec-gateway.
- Guide: Introduction · Quick Start · Policies · Configuration · Authentication · Web Integration · Operations · Troubleshooting
- Architecture: Overview · Extending
- Releases: GitHub Releases
Contributions are welcome. Read CONTRIBUTING.md for the workflow, quality gates and release process. This project follows a Code of Conduct.
Report vulnerabilities privately as described in SECURITY.md; do not open public issues for them.
CoSec is released under the Apache License 2.0. Its policy model is inspired by AWS IAM.