Skip to content

RBAC-based And Policy-based Multi-Tenant Reactive Security Framework | 基于 RBAC 和策略的多租户响应式安全框架

License

Notifications You must be signed in to change notification settings

Ahoo-Wang/CoSec

Folders and files

NameName
Last commit message
Last commit date
Mar 4, 2025
Feb 26, 2025
Jun 5, 2024
Dec 16, 2024
Nov 19, 2022
Mar 22, 2025
Mar 22, 2025
Mar 22, 2025
Mar 6, 2025
Aug 1, 2023
Apr 8, 2024
Mar 22, 2025
Dec 16, 2024
Dec 25, 2024
Feb 19, 2024
Mar 6, 2025
Mar 22, 2025
Jun 6, 2024
Feb 19, 2024
Mar 22, 2025
Dec 11, 2024
Aug 24, 2023
May 24, 2023
Nov 19, 2022
Nov 19, 2022
Nov 1, 2024
Nov 1, 2024
Mar 22, 2025
Jan 2, 2023
Mar 22, 2025
Feb 26, 2025
Jul 12, 2024
Nov 19, 2022
Mar 4, 2025

Repository files navigation

CoSec

RBAC-based And Policy-based Multi-Tenant Reactive Security Framework.

License GitHub release Maven Central Codacy Badge codecov Integration Test Status Awesome Kotlin Badge

Authentication

Authentication-Flow

Social Authentication

Social-Authentication

Authorization

Authorization-Flow

Modeling

Modeling

Gateway

Gateway

Authorization Policy

Authorization Policy

Build In Policy

ActionMatcher

ActionMatcher

How to customize ActionMatcher (SPI)

Refer to PathActionMatcher

class CustomActionMatcherFactory : ActionMatcherFactory {
    companion object {
        const val TYPE = "[CustomActionType]"
    }

    override val type: String
        get() = TYPE

    override fun create(configuration: Configuration): ConditionMatcher {
        return CustomActionMatcher(configuration)
    }
}
class CustomActionMatcher(override val configuration: Configuration) : ActionMatcher {

    override val type: String
        get() = CustomActionMatcherFactory.TYPE

    override fun match(request: Request, securityContext: SecurityContext): Boolean {
        //Custom matching logic
    }
}

META-INF/services/me.ahoo.cosec.policy.action.ActionMatcherFactory

# CustomActionMatcherFactory fully qualified name

ConditionMatcher

ConditionMatcher

How to customize ConditionMatcher (SPI)

Refer to ContainsConditionMatcher

class CustomConditionMatcherFactory : ConditionMatcherFactory {
    companion object {
        const val TYPE = "[CustomConditionType]"
    }

    override val type: String
        get() = TYPE

    override fun create(configuration: Configuration): ConditionMatcher {
        return CustomConditionMatcher(configuration)
    }
}
class CustomConditionMatcher(configuration: Configuration) :
    AbstractConditionMatcher(CustomConditionMatcherFactory.TYPE, configuration) {

    override fun internalMatch(request: Request, securityContext: SecurityContext): Boolean {
        //Custom matching logic
    }
}

META-INF/services/me.ahoo.cosec.policy.condition.ConditionMatcherFactory

# CustomConditionMatcherFactory fully qualified name

Policy Schema

Configure Policy Schema to support IDE (IntelliJ IDEA) input autocompletion.

Policy Demo

{
  "id": "id",
  "name": "name",
  "category": "category",
  "description": "description",
  "type": "global",
  "tenantId": "tenantId",
  "condition": {
    "bool": {
      "and": [
        {
          "authenticated": {}
        },
        {
          "rateLimiter": {
            "permitsPerSecond": 10
          }
        }
      ]
    }
  },
  "statements": [
    {
      "action": {
        "path": {
          "pattern": "/user/#{principal.id}/*",
          "options": {
            "caseSensitive": false,
            "separator": "/",
            "decodeAndParseSegments": false
          }
        }
      }
    },
    {
      "name": "Anonymous",
      "action": [
        "/auth/register",
        "/auth/login"
      ]
    },
    {
      "name": "UserScope",
      "action": "/user/#{principal.id}/*",
      "condition": {
        "authenticated": {}
      }
    },
    {
      "name": "Developer",
      "action": "*",
      "condition": {
        "in": {
          "part": "context.principal.id",
          "value": [
            "developerId"
          ]
        }
      }
    },
    {
      "name": "RequestOriginDeny",
      "effect": "deny",
      "action": "*",
      "condition": {
        "regular": {
          "negate": true,
          "part": "request.origin",
          "pattern": "^(http|https)://github.com"
        }
      }
    },
    {
      "name": "IpBlacklist",
      "effect": "deny",
      "action": "*",
      "condition": {
        "path": {
          "part": "request.remoteIp",
          "pattern": "192.168.0.*",
          "options": {
            "caseSensitive": false,
            "separator": ".",
            "decodeAndParseSegments": false
          }
        }
      }
    },
    {
      "name": "RegionWhitelist",
      "effect": "deny",
      "action": "*",
      "condition": {
        "regular": {
          "negate": true,
          "part": "request.attributes.ipRegion",
          "pattern": "^中国\\|0\\|(上海|广东省)\\|.*"
        }
      }
    },
    {
      "name": "AllowDeveloperOrIpRange",
      "action": "*",
      "condition": {
        "bool": {
          "and": [
            {
              "authenticated": {}
            }
          ],
          "or": [
            {
              "in": {
                "part": "context.principal.id",
                "value": [
                  "developerId"
                ]
              }
            },
            {
              "path": {
                "part": "request.remoteIp",
                "pattern": "192.168.0.*",
                "options": {
                  "caseSensitive": false,
                  "separator": ".",
                  "decodeAndParseSegments": false
                }
              }
            }
          ]
        }
      }
    },
    {
      "name": "TestContains",
      "effect": "allow",
      "action": "*",
      "condition": {
        "contains": {
          "part": "request.attributes.ipRegion",
          "value": "上海"
        }
      }
    },
    {
      "name": "TestStartsWith",
      "effect": "allow",
      "action": "*",
      "condition": {
        "startsWith": {
          "part": "request.attributes.ipRegion",
          "value": "中国"
        }
      }
    },
    {
      "name": "TestEndsWith",
      "effect": "allow",
      "action": "*",
      "condition": {
        "endsWith": {
          "part": "request.attributes.remoteIp",
          "value": ".168.0.1"
        }
      }
    }
  ]
}

App Permission Metadata Schema

Configure App Permission Schema to support IDE (IntelliJ IDEA) input autocompletion.

App Permission Demo

{
  "id": "manage",
  "condition": {
    "bool": {
      "and": [
        {
          "authenticated": {}
        },
        {
          "groupedRateLimiter": {
            "part": "request.remoteIp",
            "permitsPerSecond": 10,
            "expireAfterAccessSecond": 1000
          }
        },
        {
          "inTenant": {
            "value": "default"
          }
        }
      ]
    }
  },
  "groups": [
    {
      "name": "order",
      "description": "order management",
      "permissions": [
        {
          "id": "manage.order.ship",
          "name": "Ship",
          "description": "Ship",
          "action": "/order/ship"
        },
        {
          "id": "manage.order.issueInvoice",
          "name": "Issue an invoice",
          "description": "Issue an invoice",
          "action": "/order/issueInvoice"
        }
      ]
    }
  ]
}

Obtain the current security context

WebFlux

     Mono.deferContextual {
        val securityContext = it.getSecurityContext()
        //TODO
    }

WebMvc

SecurityContextHolder.context

OpenTelemetry

CoSec-OpenTelemetry

CoSec follows the OpenTelemetry General identity attributes specification。

CoSec-OpenTelemetry

Thanks

CoSec permission policy design refers to AWS IAM .