{"id":15651688,"url":"https://github.com/ahoo-wang/cosec","last_synced_at":"2026-04-01T19:05:26.828Z","repository":{"id":63605925,"uuid":"567999401","full_name":"Ahoo-Wang/CoSec","owner":"Ahoo-Wang","description":"RBAC-based And Policy-based Multi-Tenant Reactive Security Framework  | 基于 RBAC 和策略的多租户响应式安全框架","archived":false,"fork":false,"pushed_at":"2025-04-08T00:43:24.000Z","size":6583,"stargazers_count":35,"open_issues_count":1,"forks_count":6,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-08T01:29:13.065Z","etag":null,"topics":["authentication","authorization","cloud-native","gateway","identity","java","jwt","kotlin","microservice","multi-tenant","oauth2","policy","project-reactor","rbac","reactive","redis","security","spring-boot","spring-cloud","spring-cloud-gateway"],"latest_commit_sha":null,"homepage":"https://github.com/Ahoo-Wang/CoSec","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ahoo-Wang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-19T05:52:15.000Z","updated_at":"2025-04-08T00:43:26.000Z","dependencies_parsed_at":"2023-09-23T06:37:41.009Z","dependency_job_id":"dca7fbda-da45-491b-beea-0428a8962065","html_url":"https://github.com/Ahoo-Wang/CoSec","commit_stats":null,"previous_names":[],"tags_count":144,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoSec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoSec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoSec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ahoo-Wang%2FCoSec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ahoo-Wang","download_url":"https://codeload.github.com/Ahoo-Wang/CoSec/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248945763,"owners_count":21187380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","authorization","cloud-native","gateway","identity","java","jwt","kotlin","microservice","multi-tenant","oauth2","policy","project-reactor","rbac","reactive","redis","security","spring-boot","spring-cloud","spring-cloud-gateway"],"created_at":"2024-10-03T12:39:42.322Z","updated_at":"2026-02-04T07:14:48.796Z","avatar_url":"https://github.com/Ahoo-Wang.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CoSec\n\nRBAC-based And Policy-based Multi-Tenant Reactive Security Framework.\n\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)\n[![GitHub release](https://img.shields.io/github/release/Ahoo-Wang/CoSec.svg)](https://github.com/Ahoo-Wang/CoSec/releases)\n[![Maven Central Version](https://img.shields.io/maven-central/v/me.ahoo.cosec/cosec-core)](https://central.sonatype.com/artifact/me.ahoo.cosec/cosec-core)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/b3133cf684a74192a55abbefe2a0759a)](https://www.codacy.com/gh/Ahoo-Wang/CoSec/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=Ahoo-Wang/CoSec\u0026amp;utm_campaign=Badge_Grade)\n[![codecov](https://codecov.io/gh/Ahoo-Wang/CoSec/branch/main/graph/badge.svg?token=AL0RyJbMZv)](https://codecov.io/gh/Ahoo-Wang/CoSec)\n[![Integration Test Status](https://github.com/Ahoo-Wang/CoSec/actions/workflows/integration-test.yml/badge.svg)](https://github.com/Ahoo-Wang/CoSec)\n[![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Ahoo-Wang/CoSec)\n\n## Authentication\n\n![Authentication-Flow](document/design/assets/Authentication-Flow.svg)\n\n### Social Authentication\n\n![Social-Authentication](document/design/assets/Social-Authentication.svg)\n\n## Authorization\n\n![Authorization-Flow](document/design/assets/Authorization-Flow.svg)\n\n## Modeling\n\n![Modeling](document/design/assets/Modeling.svg)\n\n## Gateway\n\n![Gateway](document/design/assets/Gateway.svg)\n\n## Authorization Policy\n\n![Authorization Policy](document/design/assets/Authorization-Policy.svg)\n\n## Build In Policy\n\n### ActionMatcher\n\n![ActionMatcher](document/design/assets/ActionMatcher.svg)\n\n#### How to customize `ActionMatcher` (SPI)\n\n\u003e Refer to [PathActionMatcher](cosec-core/src/main/kotlin/me/ahoo/cosec/policy/action/PathActionMatcher.kt) \n\n```kotlin\nclass CustomActionMatcherFactory : ActionMatcherFactory {\n    companion object {\n        const val TYPE = \"[CustomActionType]\"\n    }\n\n    override val type: String\n        get() = TYPE\n\n    override fun create(configuration: Configuration): ConditionMatcher {\n        return CustomActionMatcher(configuration)\n    }\n}\nclass CustomActionMatcher(override val configuration: Configuration) : ActionMatcher {\n\n    override val type: String\n        get() = CustomActionMatcherFactory.TYPE\n\n    override fun match(request: Request, securityContext: SecurityContext): Boolean {\n        //Custom matching logic\n    }\n}\n```\n\n\u003e META-INF/services/me.ahoo.cosec.policy.action.ActionMatcherFactory\n\n```properties\n# CustomActionMatcherFactory fully qualified name\n```\n\n### ConditionMatcher\n\n![ConditionMatcher](document/design/assets/ConditionMatcher.svg)\n\n#### How to customize `ConditionMatcher` (SPI)\n\n\u003e Refer to [ContainsConditionMatcher](cosec-core/src/main/kotlin/me/ahoo/cosec/policy/condition/part/ContainsConditionMatcher.kt)\n\n```kotlin\nclass CustomConditionMatcherFactory : ConditionMatcherFactory {\n    companion object {\n        const val TYPE = \"[CustomConditionType]\"\n    }\n\n    override val type: String\n        get() = TYPE\n\n    override fun create(configuration: Configuration): ConditionMatcher {\n        return CustomConditionMatcher(configuration)\n    }\n}\nclass CustomConditionMatcher(configuration: Configuration) :\n    AbstractConditionMatcher(CustomConditionMatcherFactory.TYPE, configuration) {\n\n    override fun internalMatch(request: Request, securityContext: SecurityContext): Boolean {\n        //Custom matching logic\n    }\n}\n```\n\n\u003e META-INF/services/me.ahoo.cosec.policy.condition.ConditionMatcherFactory\n\n```properties\n# CustomConditionMatcherFactory fully qualified name\n```\n\n## Policy Schema\n\nConfigure [Policy Schema](schema/cosec-policy.schema.json) to support IDE ([IntelliJ IDEA](https://www.jetbrains.com/help/idea/json.html#ws_json_using_schemas)) input autocompletion.\n\n\u003e Policy Demo\n\n```json\n{\n  \"id\": \"id\",\n  \"name\": \"name\",\n  \"category\": \"category\",\n  \"description\": \"description\",\n  \"type\": \"global\",\n  \"tenantId\": \"tenantId\",\n  \"condition\": {\n    \"bool\": {\n      \"and\": [\n        {\n          \"authenticated\": {}\n        },\n        {\n          \"rateLimiter\": {\n            \"permitsPerSecond\": 10\n          }\n        }\n      ]\n    }\n  },\n  \"statements\": [\n    {\n      \"action\": {\n        \"path\": {\n          \"pattern\": \"/user/#{principal.id}/*\",\n          \"options\": {\n            \"caseSensitive\": false,\n            \"separator\": \"/\",\n            \"decodeAndParseSegments\": false\n          }\n        }\n      }\n    },\n    {\n      \"name\": \"Anonymous\",\n      \"action\": [\n        \"/auth/register\",\n        \"/auth/login\"\n      ]\n    },\n    {\n      \"name\": \"UserScope\",\n      \"action\": \"/user/#{principal.id}/*\",\n      \"condition\": {\n        \"authenticated\": {}\n      }\n    },\n    {\n      \"name\": \"Developer\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"in\": {\n          \"part\": \"context.principal.id\",\n          \"value\": [\n            \"developerId\"\n          ]\n        }\n      }\n    },\n    {\n      \"name\": \"RequestOriginDeny\",\n      \"effect\": \"deny\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"regular\": {\n          \"negate\": true,\n          \"part\": \"request.origin\",\n          \"pattern\": \"^(http|https)://github.com\"\n        }\n      }\n    },\n    {\n      \"name\": \"IpBlacklist\",\n      \"effect\": \"deny\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"path\": {\n          \"part\": \"request.remoteIp\",\n          \"pattern\": \"192.168.0.*\",\n          \"options\": {\n            \"caseSensitive\": false,\n            \"separator\": \".\",\n            \"decodeAndParseSegments\": false\n          }\n        }\n      }\n    },\n    {\n      \"name\": \"RegionWhitelist\",\n      \"effect\": \"deny\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"regular\": {\n          \"negate\": true,\n          \"part\": \"request.attributes.ipRegion\",\n          \"pattern\": \"^中国\\\\|0\\\\|(上海|广东省)\\\\|.*\"\n        }\n      }\n    },\n    {\n      \"name\": \"AllowDeveloperOrIpRange\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"bool\": {\n          \"and\": [\n            {\n              \"authenticated\": {}\n            }\n          ],\n          \"or\": [\n            {\n              \"in\": {\n                \"part\": \"context.principal.id\",\n                \"value\": [\n                  \"developerId\"\n                ]\n              }\n            },\n            {\n              \"path\": {\n                \"part\": \"request.remoteIp\",\n                \"pattern\": \"192.168.0.*\",\n                \"options\": {\n                  \"caseSensitive\": false,\n                  \"separator\": \".\",\n                  \"decodeAndParseSegments\": false\n                }\n              }\n            }\n          ]\n        }\n      }\n    },\n    {\n      \"name\": \"TestContains\",\n      \"effect\": \"allow\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"contains\": {\n          \"part\": \"request.attributes.ipRegion\",\n          \"value\": \"上海\"\n        }\n      }\n    },\n    {\n      \"name\": \"TestStartsWith\",\n      \"effect\": \"allow\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"startsWith\": {\n          \"part\": \"request.attributes.ipRegion\",\n          \"value\": \"中国\"\n        }\n      }\n    },\n    {\n      \"name\": \"TestEndsWith\",\n      \"effect\": \"allow\",\n      \"action\": \"*\",\n      \"condition\": {\n        \"endsWith\": {\n          \"part\": \"request.attributes.remoteIp\",\n          \"value\": \".168.0.1\"\n        }\n      }\n    }\n  ]\n}\n```\n\n## App Permission Metadata Schema\n\nConfigure [App Permission Schema](schema/cosec-app-permission.schema.json) to support IDE ([IntelliJ IDEA](https://www.jetbrains.com/help/idea/json.html#ws_json_using_schemas)) input autocompletion.\n\n\u003e App Permission Demo\n\n```json\n{\n  \"id\": \"manage\",\n  \"condition\": {\n    \"bool\": {\n      \"and\": [\n        {\n          \"authenticated\": {}\n        },\n        {\n          \"groupedRateLimiter\": {\n            \"part\": \"request.remoteIp\",\n            \"permitsPerSecond\": 10,\n            \"expireAfterAccessSecond\": 1000\n          }\n        },\n        {\n          \"inTenant\": {\n            \"value\": \"default\"\n          }\n        }\n      ]\n    }\n  },\n  \"groups\": [\n    {\n      \"name\": \"order\",\n      \"description\": \"order management\",\n      \"permissions\": [\n        {\n          \"id\": \"manage.order.ship\",\n          \"name\": \"Ship\",\n          \"description\": \"Ship\",\n          \"action\": \"/order/ship\"\n        },\n        {\n          \"id\": \"manage.order.issueInvoice\",\n          \"name\": \"Issue an invoice\",\n          \"description\": \"Issue an invoice\",\n          \"action\": \"/order/issueInvoice\"\n        }\n      ]\n    }\n  ]\n}\n```\n\n## Obtain the current security context\n\n### WebFlux\n\n```kotlin\n     Mono.deferContextual {\n        val securityContext = it.getSecurityContext()\n        //TODO\n    }\n```\n\n### WebMvc\n\n```\nSecurityContextHolder.context\n```\n## OpenTelemetry\n\n[CoSec-OpenTelemetry](cosec-opentelemetry)\n\n\u003e CoSec follows the OpenTelemetry [General identity attributes](https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/span-general/#general-identity-attributes) specification。\n\n![CoSec-OpenTelemetry](document/design/assets/CoSec-OpenTelemetry.png)\n\n## Thanks\n\nCoSec permission policy design refers to [AWS IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) .\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahoo-wang%2Fcosec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahoo-wang%2Fcosec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahoo-wang%2Fcosec/lists"}