Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Authz #3008

Merged
merged 25 commits into from
May 30, 2024
Merged

feat: Authz #3008

merged 25 commits into from
May 30, 2024

Conversation

markphelps
Copy link
Collaborator

@markphelps markphelps commented Apr 21, 2024

This adds authz to Flipt using Open Policy Agent for both the 'language' used to define the authz policies as well as the enforcement library.

I think that using OPA in this way continues with Flipt's ethos of:

  1. Being self-contained/not requiring external services to function (ie not requiring our users to run an authorization service like Authz/SpiceDB, Topaz, etc)
  2. Being extremely configurable/composable. (described below)

What/How

This will allow users to enable authz and configure their own policies/data in order to use existing authentication data to enforce authz.

Each API request to Flipt that is to be authorized (management API only) is annotated with a namespace, resource, subject and action similar to our already existing audit events.

The authz policies configured by operators enforce what requests are allowed given:

  1. request data (described above)
  2. authentication data (described in our docs PR)

Our existing audit events were changed to use these new request types as well, since they map 1-1 to audit events that we already publish.

Configurability

The goal is to allow operators to define their own policy rules via Rego as well as provide optional 'data' that can be used in these policies (think static mapping of user emails to roles, groups, or departments).

Currently, policies and data can only be read from the local filesystem, however, in the near future we aim to include support for:

  • git
  • oci
  • objectstores
  • k8s config maps?

Mapping Authn to Authz

A key aspect of this functionality is the mapping of authentication to authorization.
Most OIDC providers have the notion of roles and allow enriching the tokens they create with custom attributes such as roles.

OIDC Providers:

In our docs PR, I have written a guide demonstrating how to map a user to a role using Keycloak, that can then be enforced by a policy in Flipt using OPA.

We will likely need more documentation and examples on writing policies in the future.

We have also chosen to make this functionality 'experimental' until we add extensive integration tests and have had the ability to get it in user's hands and garner feedback.

cc @piclemx @erka @GeorgeMac

feat: impl authz middleware

feat: impl authz middleware

chore: fix panic and bad redux selector

chore: fmt ui

chore: refactor

chore: fix build, change to single role, default role

chore: fix build, change to single role, default role

chore: rm unneeded files

feat: configurable roles/policies

chore: config schema and tests

chore: mv back events to audit package

chore: reset ui folder

chore: revert ui back to main

chore: policy schema, visibility of errors

chore: add policy schema test

chore: rebase on main

Signed-off-by: Mark Phelps <[email protected]>
markphelps and others added 12 commits May 20, 2024 19:09
* chore: fix tests, add role attribute path / role mapping to oidc server tests

Signed-off-by: Mark Phelps <[email protected]>

* chore: authz middleware tests

Signed-off-by: Mark Phelps <[email protected]>

* chore: fix audit tests

Signed-off-by: Mark Phelps <[email protected]>

* chore: proto regen

Signed-off-by: Mark Phelps <[email protected]>

* chore: try to fix marshal audit events behaviour

Signed-off-by: Mark Phelps <[email protected]>

* chore: fix failing test

Signed-off-by: Mark Phelps <[email protected]>

---------

Signed-off-by: Mark Phelps <[email protected]>
Signed-off-by: Mark Phelps <[email protected]>
Signed-off-by: Mark Phelps <[email protected]>
chore: refactor request models to include scope
…3108)

* refactor(server/authz): rename scope to resource

Signed-off-by: George MacRorie <[email protected]>

* feat(config/authz): add policy and data source configuration

Signed-off-by: George MacRorie <[email protected]>

* refactor(server/authz): make policy and data external dependencies

Signed-off-by: George MacRorie <[email protected]>

* refactor(cmd/grpc): integrate new authz Engine changes

Signed-off-by: George MacRorie <[email protected]>

* fix(server/authz): ensure error is captured in return

Signed-off-by: George MacRorie <[email protected]>

* fix(config): allow policy and data sources to be empty

Signed-off-by: George MacRorie <[email protected]>

* refactor(server/authz): support separate poll durations for policy and data

Signed-off-by: George MacRorie <[email protected]>

* fix(config): validate non zero poll duration for authz sources

Signed-off-by: George MacRorie <[email protected]>

* fix(cmd/grpc): calls to authz engine with changes to polling

Signed-off-by: George MacRorie <[email protected]>

---------

Signed-off-by: George MacRorie <[email protected]>
@markphelps markphelps marked this pull request as ready for review May 27, 2024 14:32
@markphelps markphelps requested a review from a team as a code owner May 27, 2024 14:32
@markphelps markphelps marked this pull request as draft May 27, 2024 14:32
@GeorgeMac
Copy link
Member

I'll just add that; while there are limitations with OIDC providers r.e. doing the role management on the IdP itself, you can always express role mappings in the Rego data. Ultimately this is an email to permissions mapping directly in the data payload. Doesn't necessarily need to include roles, but roles and mappings in the data can be expressed for readability and DRYing up the definitions.

The Rego/OPA Playground demonstrates this if you choose the RBAC scenario.
They have user_roles and role_grants sections in their data like so:

{
    "user_roles": {
        "alice": [
            "admin"
        ],
        "bob": [
            "employee",
            "billing"
        ],
        "eve": [
            "customer"
        ]
    },
    "role_grants": {
        "customer": [
            {
                "action": "read",
                "type": "dog"
            },
            {
                "action": "read",
                "type": "cat"
            },
            {
                "action": "adopt",
                "type": "dog"
            },
            {
                "action": "adopt",
                "type": "cat"
            }
        ],
        "employee": [
            {
                "action": "read",
                "type": "dog"
            },
            {
                "action": "read",
                "type": "cat"
            },
            {
                "action": "update",
                "type": "dog"
            },
            {
                "action": "update",
                "type": "cat"
            }
        ],
        "billing": [
            {
                "action": "read",
                "type": "finance"
            },
            {
                "action": "update",
                "type": "finance"
            }
        ]
    }
}

Then the policy itself knows to perform the mapping from auth email to granted permissions.
It just means in the datasource you will need to manage the user role mappings there, instead of in e.g. Google.
If e.g. these were in Git, that might be a familiar experience for those managing e.g. k8s role mappings in Git via something like Argo / Flux.

* chore: go mod tidy

Signed-off-by: Mark Phelps <[email protected]>

* chore: set raw claims if they exist in authz metadata

Signed-off-by: Mark Phelps <[email protected]>

* chore: fix authn oidc server test

Signed-off-by: Mark Phelps <[email protected]>

* chore: skip authz on auth public server

Signed-off-by: Mark Phelps <[email protected]>

* chore: log for debugging

Signed-off-by: Mark Phelps <[email protected]>

---------

Signed-off-by: Mark Phelps <[email protected]>
* chore: go mod tidy

Signed-off-by: Mark Phelps <[email protected]>

* fix: authz endpoint skip for getauthself/deleteauthself

Signed-off-by: Mark Phelps <[email protected]>

* chore: rm claims unmarshal for now

* chore: make authorization experimental

Signed-off-by: Mark Phelps <[email protected]>

* chore: add request methods to auth requests

Signed-off-by: Mark Phelps <[email protected]>

* chore: add schema

* chore: set package name to flipt.authz.v1

* chore: fix telemetry test

Signed-off-by: Mark Phelps <[email protected]>

---------

Signed-off-by: Mark Phelps <[email protected]>
@markphelps markphelps marked this pull request as ready for review May 29, 2024 20:08
@markphelps markphelps changed the title feat(draft): Authz feat: Authz May 29, 2024
@markphelps
Copy link
Collaborator Author

cc @smittysmee

internal/config/cache.go Outdated Show resolved Hide resolved
Copy link
Member

@GeorgeMac GeorgeMac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. There is one bit of go fmting left I think. Otherwise, good to go.

@markphelps markphelps added the automerge Used by Kodiak bot to automerge PRs label May 30, 2024
@kodiakhq kodiakhq bot merged commit 6ab00f7 into main May 30, 2024
30 of 32 checks passed
@kodiakhq kodiakhq bot deleted the authz branch May 30, 2024 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Used by Kodiak bot to automerge PRs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants