-
Notifications
You must be signed in to change notification settings - Fork 15
Feature/authz external #874
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,3 +29,4 @@ docs/website/.vite | |
| /*.key | ||
|
|
||
| vendor | ||
| /.run/ | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,53 @@ | ||||||
| package authz | ||||||
|
|
||||||
| import ( | ||||||
| "net/http" | ||||||
|
|
||||||
| "github.com/coupergateway/couper/errors" | ||||||
| ) | ||||||
|
|
||||||
| type DestinationRoundTripper interface { | ||||||
| http.RoundTripper | ||||||
| GetDestination() string | ||||||
| } | ||||||
|
|
||||||
| // External authorization calls the configured origin with customized request context. | ||||||
| // The origin must respond with 200 OK to have a valid client request. | ||||||
| type External struct { | ||||||
| origin DestinationRoundTripper | ||||||
| includeMetadataTLS bool | ||||||
| // TODO | ||||||
| // conf for who to what | ||||||
| // params, header or body or both | ||||||
| // pass certificate | ||||||
| } | ||||||
|
|
||||||
| type clientRequest struct { | ||||||
| Method string | ||||||
| URL string | ||||||
| Header http.Header | ||||||
| } | ||||||
|
|
||||||
| type authContext struct { | ||||||
| Source any // previous hop | ||||||
| Destination any // target backend (origin) | ||||||
| ClientRequest clientRequest // simplified form / serialized | ||||||
| Route any | ||||||
| Metadata any // user / hcl provided | ||||||
| MetadataTLS any // tls conn infos / opt in | ||||||
| } | ||||||
|
|
||||||
| func NewExternal(origin DestinationRoundTripper, includeMetadataTLS bool) (*External, error) { | ||||||
| return &External{ | ||||||
| origin: origin, | ||||||
| includeMetadataTLS: includeMetadataTLS, | ||||||
| }, nil | ||||||
| } | ||||||
|
Comment on lines
+40
to
+45
|
||||||
|
|
||||||
| func (c *External) Validate(req *http.Request) error { | ||||||
| if c.origin == nil { | ||||||
| return errors.AccessControl.Message("origin required") | ||||||
| } | ||||||
| //TODO implement me | ||||||
| panic("implement me") | ||||||
|
||||||
| panic("implement me") | |
| return errors.AccessControl.Message("not implemented") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package config | ||
|
|
||
| import ( | ||
| "github.com/hashicorp/hcl/v2" | ||
| "github.com/hashicorp/hcl/v2/hclsyntax" | ||
| ) | ||
|
|
||
| type OpenFGAEntity struct { | ||
| Namespace string `hcl:"namespace" docs:"The namespace of the entity."` | ||
| Name hcl.Expression `hcl:"name" docs:"The name or identifier of the entity."` | ||
| } | ||
|
|
||
| type OpenFGAEntityRelation struct { | ||
| Name hcl.Expression `hcl:"name" docs:"The name of the relation."` | ||
| } | ||
|
|
||
| type AuthZOpenFGA struct { | ||
| User *OpenFGAEntity `hcl:"user,block" docs:"The user entity."` | ||
| Relation *OpenFGAEntityRelation `hcl:"relation,block" docs:"The relation name."` | ||
| Object *OpenFGAEntity `hcl:"object,block" docs:"The object entity."` | ||
| StoreID string `hcl:"store_id" docs:"The store ID to use for authorization against the OpenFGA server."` | ||
| ModelID string `hcl:"model_id,optional" docs:"The model ID to use for authorization against the OpenFGA store. If omitted, the latest store model is used."` | ||
| Remain hcl.Body `hcl:",remain"` | ||
| } | ||
|
|
||
| type AuthZExternal struct { | ||
| BackendName string `hcl:"backend" docs:"References a default [backend](/configuration/block/backend) in [definitions](/configuration/block/definitions) for authZ requests. Mutually exclusive with {backend} block."` | ||
| URL string `hcl:"url,optional" docs:"The URL to call for authorization."` | ||
| IncludeTLS bool `hcl:"include_tls,optional" docs:"Include TLS information in the authorization request."` | ||
| Name string `hcl:"name,label" docs:"The name of the authorization."` | ||
| OpenFGA *AuthZOpenFGA `hcl:"openfga,block" docs:"Configure an [OpenFGA](/configuration/block/authz_external/openfga) authorization."` | ||
| Remain hcl.Body `hcl:",remain"` | ||
|
|
||
| // Internally used | ||
| Backend *hclsyntax.Body | ||
| } | ||
|
|
||
| func (a *AuthZExternal) Prepare(backendFunc PrepareBackendFunc) (err error) { | ||
| if a.URL != "" { | ||
| a.Backend, err = backendFunc(a.BackendName, a.Name, a) | ||
| return err | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func (a *AuthZExternal) HCLBody() *hclsyntax.Body { | ||
| return a.Remain.(*hclsyntax.Body) | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -17,6 +17,7 @@ import ( | |||||
| "github.com/sirupsen/logrus" | ||||||
|
|
||||||
| ac "github.com/coupergateway/couper/accesscontrol" | ||||||
| "github.com/coupergateway/couper/accesscontrol/authz" | ||||||
| "github.com/coupergateway/couper/accesscontrol/jwk" | ||||||
| "github.com/coupergateway/couper/cache" | ||||||
| "github.com/coupergateway/couper/config" | ||||||
|
|
@@ -361,13 +362,13 @@ func NewServerConfiguration(conf *config.Couper, log *logrus.Entry, memStore *ca | |||||
| protectedHandler = epHandler | ||||||
| } else { | ||||||
| permissionsControl := ac.NewPermissionsControl(requiredPermissionExpr) | ||||||
| permissionsErrorHandler, _, err := newErrorHandler(confCtx, conf, &protectedOptions{ | ||||||
| permissionsErrorHandler, _, permErr := newErrorHandler(confCtx, conf, &protectedOptions{ | ||||||
| epOpts: epOpts, | ||||||
| memStore: memStore, | ||||||
| srvOpts: serverOptions, | ||||||
| }, log, errorHandlerDefinitions, "api", "endpoint") // sequence of ref is important: api, endpoint (endpoint error_handler overrides api error_handler) | ||||||
| if err != nil { | ||||||
| return nil, err | ||||||
| if permErr != nil { | ||||||
| return nil, permErr | ||||||
| } | ||||||
|
|
||||||
| protectedHandler = middleware.NewErrorHandler(permissionsControl.Validate, permissionsErrorHandler)(epHandler) | ||||||
|
|
@@ -510,12 +511,22 @@ func configureOidcConfigs(conf *config.Couper, confCtx *hcl.EvalContext, log *lo | |||||
| return oidcConfigs, nil | ||||||
| } | ||||||
|
|
||||||
| func configureAccessControls(conf *config.Couper, confCtx *hcl.EvalContext, log *logrus.Entry, | ||||||
| memStore *cache.MemoryStore, oidcConfigs oidc.Configs) (ACDefinitions, error) { | ||||||
|
|
||||||
| func configureAccessControls( | ||||||
| conf *config.Couper, confCtx *hcl.EvalContext, log *logrus.Entry, | ||||||
| memStore *cache.MemoryStore, oidcConfigs oidc.Configs, | ||||||
| ) (ACDefinitions, error) { | ||||||
| accessControls := make(ACDefinitions) | ||||||
|
|
||||||
| if conf.Definitions != nil { | ||||||
| for _, authZExternal := range conf.Definitions.AuthZExternal { | ||||||
| confErr := errors.Configuration.Label(authZExternal.Name) | ||||||
| authZExt, err := authz.NewExternal(nil, false) | ||||||
|
||||||
| authZExt, err := authz.NewExternal(nil, false) | |
| authZExt, err := authz.NewExternal(authZExternal.Origin, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
clientRequestandauthContexttypes are defined but never used in the code. These should either be utilized in the implementation or removed to avoid dead code.