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

Latest commit

63fa6f8 · Jan 7, 2025
Nov 14, 2024
May 24, 2023
Jun 5, 2024
Dec 16, 2024
Nov 19, 2022
Jan 7, 2025
Dec 25, 2024
Dec 7, 2023
Aug 1, 2023
Apr 8, 2024
Jan 10, 2023
Dec 16, 2024
Dec 25, 2024
Aug 24, 2023
Feb 19, 2024
Dec 16, 2024
Dec 16, 2024
Jun 6, 2024
Feb 19, 2024
Jan 7, 2025
Dec 11, 2024
Aug 24, 2023
May 24, 2023
Nov 19, 2022
Nov 19, 2022
Nov 1, 2024
Nov 1, 2024
Jun 18, 2024
Jan 2, 2023
Jan 7, 2025
Dec 21, 2024
Jul 12, 2024
Nov 19, 2022
Feb 19, 2024

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 .