Skip to content

Commit

Permalink
Added authz support for mgmt
Browse files Browse the repository at this point in the history
  • Loading branch information
slavikm committed Nov 2, 2023
1 parent 0580ecd commit 1916141
Show file tree
Hide file tree
Showing 6 changed files with 523 additions and 0 deletions.
176 changes: 176 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ These sections show how to use the SDK to perform API management functions. Befo
9. [Manage JWTs](#manage-jwts)
10. [Search Audit](#search-audit)
11. [Embedded Links](#embedded-links)
12. [Manage Authz](#manage-authz)

If you wish to run any of our code samples and play with them, check out our [Code Examples](#code-examples) section.

Expand Down Expand Up @@ -904,6 +905,181 @@ if err == nil {
}
```

### Manage Authz

Descope supports full relation based access control (ReBAC) using a zanzibar like schema and operations.
A schema is comprized of namespaces (entities like documents, folders, orgs, etc.) and each namespace has relation definitions to define relations.
Each relation definition can be simple (either you have it or not) or complex (union of nodes).

A simple example for a file system like schema would be:

```yaml
# Example schema for the authz tests
name: Files
namespaces:
- name: org
relationDefinitions:
- name: parent
- name: member
complexDefinition:
nType: union
children:
- nType: child
expression:
neType: self
- nType: child
expression:
neType: relationLeft
relationDefinition: parent
relationDefinitionNamespace: org
targetRelationDefinition: member
targetRelationDefinitionNamespace: org
- name: folder
relationDefinitions:
- name: parent
- name: owner
complexDefinition:
nType: union
children:
- nType: child
expression:
neType: self
- nType: child
expression:
neType: relationRight
relationDefinition: parent
relationDefinitionNamespace: folder
targetRelationDefinition: owner
targetRelationDefinitionNamespace: folder
- name: editor
complexDefinition:
nType: union
children:
- nType: child
expression:
neType: self
- nType: child
expression:
neType: relationRight
relationDefinition: parent
relationDefinitionNamespace: folder
targetRelationDefinition: editor
targetRelationDefinitionNamespace: folder
- nType: child
expression:
neType: targetSet
targetRelationDefinition: owner
targetRelationDefinitionNamespace: folder
- name: viewer
complexDefinition:
nType: union
children:
- nType: child
expression:
neType: self
- nType: child
expression:
neType: relationRight
relationDefinition: parent
relationDefinitionNamespace: folder
targetRelationDefinition: viewer
targetRelationDefinitionNamespace: folder
- nType: child
expression:
neType: targetSet
targetRelationDefinition: editor
targetRelationDefinitionNamespace: folder
- name: doc
relationDefinitions:
- name: parent
- name: owner
complexDefinition:
nType: union
children:
- nType: child
expression:
neType: self
- nType: child
expression:
neType: relationRight
relationDefinition: parent
relationDefinitionNamespace: doc
targetRelationDefinition: owner
targetRelationDefinitionNamespace: folder
- name: editor
complexDefinition:
nType: union
children:
- nType: child
expression:
neType: self
- nType: child
expression:
neType: relationRight
relationDefinition: parent
relationDefinitionNamespace: doc
targetRelationDefinition: editor
targetRelationDefinitionNamespace: folder
- nType: child
expression:
neType: targetSet
targetRelationDefinition: owner
targetRelationDefinitionNamespace: doc
- name: viewer
complexDefinition:
nType: union
children:
- nType: child
expression:
neType: self
- nType: child
expression:
neType: relationRight
relationDefinition: parent
relationDefinitionNamespace: doc
targetRelationDefinition: viewer
targetRelationDefinitionNamespace: folder
- nType: child
expression:
neType: targetSet
targetRelationDefinition: editor
targetRelationDefinitionNamespace: doc
```
Descope SDK allows you to fully manage the schema and relations as well as perform simple (and not so simple) checks regarding the existence of relations.
```go
// Load the existing schema
schema, err := descopeClient.Management.Authz().LoadSchema()
if err != nil {
// handle error
}

// Save schema and make sure to remove all namespaces not listed
err := descopeClient.Management.Authz().SaveSchema(schema, true)

// Create a relation between a resource and user
err := descopeClient.Management.Authz().CreateRelations([]*descope.AuthzRelation {
{
resource: "some-doc",
relationDefinition: "owner",
namespace: "doc",
target: "u1",
},
})

// Check if target has the relevant relation
// The answer should be true because an owner is also a viewer
relations, err := descopeClient.Management.Authz().HasRelations([]*descope.AuthzRelationQuery{
{
resource: "some-doc",
relationDefinition: "viewer",
namespace: "doc",
target: "u1",
}
})
```

## Code Examples

You can find various usage examples in the [examples folder](https://github.com/descope/go-sdk/blob/main/examples).
Expand Down
91 changes: 91 additions & 0 deletions descope/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,21 @@ var (
projectExport: "mgmt/project/export",
projectImport: "mgmt/project/import",
auditSearch: "mgmt/audit/search",
authzSchemaSave: "mgmt/authz/schema/save",
authzSchemaDelete: "mgmt/authz/schema/delete",
authzSchemaLoad: "mgmt/authz/schema/load",
authzNSSave: "mgmt/authz/ns/save",
authzNSDelete: "mgmt/authz/ns/delete",
authzRDSave: "mgmt/authz/rd/save",
authzRDDelete: "mgmt/authz/rd/delete",
authzRECreate: "mgmt/authz/re/create",
authzREDelete: "mgmt/authz/re/delete",
authzREDeleteResources: "mgmt/authz/re/deleteresources",
authzREHasRelations: "mgmt/authz/re/has",
authzREWho: "mgmt/authz/re/who",
authzREResource: "mgmt/authz/re/resource",
authzRETargets: "mgmt/authz/re/targets",
authzRETargetAll: "mgmt/authz/re/targetall",
},
logout: "auth/logout",
logoutAll: "auth/logoutall",
Expand Down Expand Up @@ -268,6 +283,22 @@ type mgmtEndpoints struct {
projectImport string

auditSearch string

authzSchemaSave string
authzSchemaDelete string
authzSchemaLoad string
authzNSSave string
authzNSDelete string
authzRDSave string
authzRDDelete string
authzRECreate string
authzREDelete string
authzREDeleteResources string
authzREHasRelations string
authzREWho string
authzREResource string
authzRETargets string
authzRETargetAll string
}

func (e *endpoints) SignInOTP() string {
Expand Down Expand Up @@ -653,6 +684,66 @@ func (e *endpoints) ManagementAuditSearch() string {
return path.Join(e.version, e.mgmt.auditSearch)
}

func (e *endpoints) ManagementAuthzSchemaSave() string {
return path.Join(e.version, e.mgmt.authzSchemaSave)
}

func (e *endpoints) ManagementAuthzSchemaDelete() string {
return path.Join(e.version, e.mgmt.authzSchemaDelete)
}

func (e *endpoints) ManagementAuthzSchemaLoad() string {
return path.Join(e.version, e.mgmt.authzSchemaLoad)
}

func (e *endpoints) ManagementAuthzNSSave() string {
return path.Join(e.version, e.mgmt.authzNSSave)
}

func (e *endpoints) ManagementAuthzNSDelete() string {
return path.Join(e.version, e.mgmt.authzNSDelete)
}

func (e *endpoints) ManagementAuthzRDSave() string {
return path.Join(e.version, e.mgmt.authzRDSave)
}

func (e *endpoints) ManagementAuthzRDDelete() string {
return path.Join(e.version, e.mgmt.authzRDDelete)
}

func (e *endpoints) ManagementAuthzRECreate() string {
return path.Join(e.version, e.mgmt.authzRECreate)
}

func (e *endpoints) ManagementAuthzREDelete() string {
return path.Join(e.version, e.mgmt.authzREDelete)
}

func (e *endpoints) ManagementAuthzREDeleteResources() string {
return path.Join(e.version, e.mgmt.authzREDeleteResources)
}

func (e *endpoints) ManagementAuthzREHasRelations() string {
return path.Join(e.version, e.mgmt.authzREHasRelations)
}

func (e *endpoints) ManagementAuthzREWho() string {
return path.Join(e.version, e.mgmt.authzREWho)
}

func (e *endpoints) ManagementAuthzREResource() string {
return path.Join(e.version, e.mgmt.authzREResource)
}

func (e *endpoints) ManagementAuthzRETargets() string {
return path.Join(e.version, e.mgmt.authzRETargets)
}

func (e *endpoints) ManagementAuthzRETargetAll() string {
return path.Join(e.version, e.mgmt.authzRETargetAll)
}

type sdkInfo struct {
name string
version string
Expand Down
7 changes: 7 additions & 0 deletions descope/internal/mgmt/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type managementService struct {
flow sdk.Flow
project sdk.Project
audit sdk.Audit
authz sdk.Authz
}

func NewManagement(conf ManagementParams, c *api.Client) *managementService {
Expand All @@ -47,6 +48,7 @@ func NewManagement(conf ManagementParams, c *api.Client) *managementService {
service.flow = &flow{managementBase: base}
service.project = &project{managementBase: base}
service.audit = &audit{managementBase: base}
service.authz = &authz{managementBase: base}
return service
}

Expand Down Expand Up @@ -105,6 +107,11 @@ func (mgmt *managementService) Audit() sdk.Audit {
return mgmt.audit
}

func (mgmt *managementService) Authz() sdk.Authz {
mgmt.ensureManagementKey()
return mgmt.authz
}

func (mgmt *managementService) ensureManagementKey() {
if mgmt.conf.ManagementKey == "" {
logger.LogInfo("Management key is missing, make sure to add it in the Config struct or the environment variable \"%s\"", descope.EnvironmentVariableManagementKey) // notest
Expand Down
Loading

0 comments on commit 1916141

Please sign in to comment.