Documentation ¶
Overview ¶
Package grpc_opa_middleware implements a gRPC middleware for sending requests to Opa.
Index ¶
- Constants
- Variables
- func AddOuterParens(sqlStr string) string
- func EntitlementsCtxOp(ctx context.Context) *opbench
- func FlattenRawEntitledFeatures(efIfc interface{}) ([]string, error)
- func FromContext(ctx context.Context) interface{}
- func IsNilInterface(i interface{}) bool
- func NullClaimsVerifier([]string, []string) (string, []error)
- func StreamServerInterceptor(application string, opts ...Option) grpc.StreamServerInterceptor
- func UnaryServerInterceptor(application string, opts ...Option) grpc.UnaryServerInterceptor
- func UnverifiedClaimFromBearers(bearer, newBearer []string) (string, []error)
- type ABACKey
- type AcctEntitlementsApiInput
- type AcctEntitlementsApiResult
- type AcctEntitlementsType
- type AuthorizeFn
- type Authorizer
- type ClaimsVerifier
- type Config
- type CurrentUserCompartmentsResult
- type DecisionInput
- type DecisionInputHandler
- type DefaultAuthorizer
- func (a *DefaultAuthorizer) AffirmAuthorization(ctx context.Context, fullMethod string, grpcReq interface{}) (context.Context, error)
- func (a *DefaultAuthorizer) Evaluate(ctx context.Context, fullMethod string, grpcReq interface{}, ...) (bool, context.Context, error)
- func (a *DefaultAuthorizer) FilterCompartmentFeatures(ctx context.Context, features FilterCompartmentFeaturesType) (FilterCompartmentFeaturesType, error)
- func (a *DefaultAuthorizer) FilterCompartmentPermissions(ctx context.Context, permissions FilterCompartmentPermissionsType) (FilterCompartmentPermissionsType, error)
- func (a *DefaultAuthorizer) GetAcctEntitlements(ctx context.Context, accountIDs, serviceNames []string) (*AcctEntitlementsType, error)
- func (a *DefaultAuthorizer) GetAcctEntitlementsBytes(ctx context.Context, accountIDs, serviceNames []string) ([]byte, error)
- func (a *DefaultAuthorizer) GetCurrentUserCompartments(ctx context.Context) ([]string, error)
- func (a *DefaultAuthorizer) OpaQuery(ctx context.Context, decisionDocument string, opaReq, opaResp interface{}) error
- func (a DefaultAuthorizer) String() string
- func (a *DefaultAuthorizer) Validate(ctx context.Context, fullMethod string, grpcReq interface{}, ...) (interface{}, error)
- type DefaultDecisionInputer
- type EntitledFeaturesKeyType
- type FilterCompartmentFeaturesInput
- type FilterCompartmentFeaturesResult
- type FilterCompartmentFeaturesType
- type FilterCompartmentPermissionsInput
- type FilterCompartmentPermissionsResult
- type FilterCompartmentPermissionsType
- type OPARequest
- type OPAResponse
- type ObligationKey
- type ObligationsEnum
- type ObligationsNode
- func (o8n *ObligationsNode) DeepSort()
- func (o8n *ObligationsNode) IsShallowEmpty() bool
- func (o8n *ObligationsNode) ShallowLength() int
- func (lhs *ObligationsNode) ShallowLessThan(rhs *ObligationsNode) bool
- func (o8n *ObligationsNode) String() string
- func (o8n *ObligationsNode) ToSQLPredicate(sqlc *sqlcompiler.SQLCompiler) (string, error)
- type OpaEvaluator
- type Option
- func WithAcctEntitlementsApiPath(acctEntitlementsApi string) Option
- func WithAddress(address string) Option
- func WithAuthorizer(auther ...Authorizer) Option
- func WithClaimsVerifier(claimsVerifier ClaimsVerifier) Option
- func WithDecisionInputHandler(decisionHandler DecisionInputHandler) Option
- func WithEntitledServices(entitledServices ...string) Option
- func WithFilterComparmentFeaturesApiPath(filterCompartmentFeatsApi string) Option
- func WithFilterComparmentPermissionsApiPath(filterCompartmentPermsApi string) Option
- func WithHTTPClient(client *http.Client) Option
- func WithOpaClienter(clienter opa_client.Clienter) Option
- func WithOpaEvaluator(opaEvaluator OpaEvaluator) Option
- type Payload
- type WrappedSrvStream
Constants ¶
const ( // DefaultValidatePath is default OPA path to perform authz validation DefaultValidatePath = "v1/data/authz/rbac/validate_v1" REDACTED = "redacted" TypeKey = ABACKey("ABACType") VerbKey = ABACKey("ABACVerb") ObKey = ObligationKey("obligations") )
const ( // DefaultFilterCompartmentPermissionsApiPath is default OPA path to filter compartment permissions DefaultFilterCompartmentPermissionsApiPath = "v1/data/authz/rbac/filter_compartment_permissions_api" // DefaultFilterCompartmentFeaturesApiPath is default OPA path to filter compartment features DefaultFilterCompartmentFeaturesApiPath = "v1/data/authz/rbac/filter_compartment_features_api" )
const (
// DefaultAcctEntitlementsApiPath is default OPA path to fetch acct entitlements
DefaultAcctEntitlementsApiPath = "v1/data/authz/rbac/acct_entitlements_api"
)
const (
// DefaultCurrentUserCompartmentsPath is default OPA path to fetch current user's compartments
DefaultCurrentUserCompartmentsPath = "v1/data/authz/rbac/current_user_compartments"
)
const EntitledFeaturesKey = EntitledFeaturesKeyType("entitled_features")
EntitledFeaturesKey is the entitled_features key stored in the caller's context. It is also the entitled_features key in the OPA response.
Variables ¶
var ( ErrForbidden = status.Errorf(codes.PermissionDenied, "Request forbidden: not authorized") ErrUnknown = status.Errorf(codes.Unknown, "Unknown error") ErrInvalidArg = status.Errorf(codes.InvalidArgument, "Invalid argument") )
var ( // Application is set at initization Application string ErrNoCredentials = errors.New("no credentials found") )
var ErrInvalidEntitledFeatures = status.Errorf(codes.Internal, "Invalid entitled_features")
ErrInvalidEntitledFeatures is returned upon invalid entitled_features
var ( // ErrInvalidObligations is returned upon invalid obligations ErrInvalidObligations = status.Errorf(codes.Internal, "Invalid obligations") )
var (
SERVICENAME = "opa"
)
Override to set your servicename
Functions ¶
func AddOuterParens ¶ added in v0.0.2
AddOuterParens adds outer parentheses only if required
func EntitlementsCtxOp ¶ added in v0.0.6
EntitlementsCtxOp is a simple operator to manipulate over entitled features in context. It retrieves entitled features from the context and converts them to a structure that is easy to operate on. Returned value includes only unimported fields and is designed to chain other methods that it has.
func FlattenRawEntitledFeatures ¶ added in v0.0.5
FlattenRawEntitledFeatures flattens raw entitled_features into an array The raw JSON-unmarshaled entitled_features is of the form:
map[string]interface {}{"lic":[]interface {}{"dhcp", "ipam"}, "rpz":[]interface {}{"bogon", "malware"}}}
Returns flattened array of the form:
[]string{"lic.dhcp", "lic.ipam", "rpz.bogon", "rpz.malware"}
func FromContext ¶
FromContext retrieves authZ information from the Context
func IsNilInterface ¶
func IsNilInterface(i interface{}) bool
IsNilInterface returns whether the interface parameter is nil Ref: https://mangatmodi.medium.com/go-check-nil-interface-the-right-way-d142776edef1
func NullClaimsVerifier ¶ added in v0.0.7
NullClaimsVerifier does nothing and just returns non-error empty bearer string.
func StreamServerInterceptor ¶
func StreamServerInterceptor(application string, opts ...Option) grpc.StreamServerInterceptor
StreamServerInterceptor returns a new Stream client interceptor that optionally logs the execution of external gRPC calls.
func UnaryServerInterceptor ¶
func UnaryServerInterceptor(application string, opts ...Option) grpc.UnaryServerInterceptor
UnaryServerInterceptor returns a new unary client interceptor that optionally logs the execution of external gRPC calls.
func UnverifiedClaimFromBearers ¶
UnverifiedClaimFromBearers parses JWT claims from 'bearer' and 'newBearer' strings, and returns the chosen valid bearer string ('newBearer' has precedence over 'bearer'). It is similar to atlas_claims.UnverifiedClaimFromBearers(), but returns the chosen raw bearer string instead of the decoded claims. (https://github.com/infobloxopen/atlas-claims/blob/c116bfcdadb14433dcd41c771b9755f7f640da33/parser.go#L36) None of the claims are checked, including IssuedAt(iat), NotBefore(nbf), nor ExpiresAt(exp) claims. The signature is also not checked. Returns error if bearer strings are not valid JWT (eg: empty bearer string is invalid).
Types ¶
type AcctEntitlementsApiInput ¶ added in v0.0.7
type AcctEntitlementsApiInput struct { AccountIDs []string `json:"acct_entitlements_acct_ids"` ServiceNames []string `json:"acct_entitlements_services"` }
AcctEntitlementsApiInput is the input payload for acct_entitlements_api
type AcctEntitlementsApiResult ¶ added in v0.0.7
type AcctEntitlementsApiResult struct {
Result *AcctEntitlementsType `json:"result"`
}
AcctEntitlementsApiResult is the data type json.Unmarshaled from OPA RESTAPI query to acct_entitlements_api
type AcctEntitlementsType ¶ added in v0.0.7
AcctEntitlementsType is a convenience data type, returned by GetAcctEntitlements() (map of acct_id to map of service to array of features)
type AuthorizeFn ¶
type AuthorizeFn func(ctx context.Context, fullMethodName string, grpcReq interface{}, opaEvaluator OpaEvaluator) (bool, context.Context, error)
func (AuthorizeFn) Evaluate ¶
func (a AuthorizeFn) Evaluate(ctx context.Context, fullMethod string, grpcReq interface{}, opaEvaluator OpaEvaluator) (bool, context.Context, error)
func (AuthorizeFn) OpaQuery ¶
func (a AuthorizeFn) OpaQuery(opaReq, opaResp interface{}) error
type Authorizer ¶
type Authorizer interface { // Validate is called with the grpc request's method passing the grpc request Context. // If the handler is executed, the request will be sent to Opa. // Unlike Evaluate, it only returns the raw Opa response, it does not parse the results. Validate(ctx context.Context, fullMethod string, grpcReq interface{}, opaEvaluator OpaEvaluator) (interface{}, error) // Evaluate is called with the grpc request's method passing the grpc request Context. // If the handler is executed, the request will be sent to Opa. Opa's response // will be unmarshaled using JSON into the provided response. // Evaluate returns true if the request is authorized. // A modified context is returned containing the entitled_features and obligations // parsed from the Opa response. // The modified context can be passed to subsequent HTTP Handler. Evaluate(ctx context.Context, fullMethod string, grpcReq interface{}, opaEvaluator OpaEvaluator) (bool, context.Context, error) // OpaQuery executes query of the specified decisionDocument against OPA. // If decisionDocument is "", then the query is executed against the default decision document configured in OPA. OpaQuery(ctx context.Context, decisionDocument string, opaReq, opaResp interface{}) error }
Authorizer interface is implemented for making arbitrary requests to Opa.
type ClaimsVerifier ¶ added in v0.0.3
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
func NewDefaultConfig ¶ added in v0.0.10
NewDefaultConfig returns a new default Config. If WithAuthorizer() option is not specified, then a new DefaultAuthorizer is used.
type CurrentUserCompartmentsResult ¶ added in v0.0.13
type CurrentUserCompartmentsResult struct {
Result []string `json:"result"`
}
CurrentUserCompartmentsResult is the data type json.Unmarshaled from OPA RESTAPI query to current_user_compartments rego rule
type DecisionInput ¶
type DecisionInput struct { Type string `json:"type"` // Object/resource-type to match Verb string `json:"verb"` // Verb to match SealCtx []interface{} `json:"ctx"` // Array of app/service-specific context data to match DecisionDocument string `json:"-"` // OPA decision document to query, by default "", }
DecisionInput is app/service-specific data supplied by app/service ABAC requests
type DecisionInputHandler ¶
type DecisionInputHandler interface { // GetDecisionInput returns an app/service-specific DecisionInput. // A nil DecisionInput should NOT be returned unless error. GetDecisionInput(ctx context.Context, fullMethod string, grpcReq interface{}) (*DecisionInput, error) }
fullMethod is of the form "Service.FullMethod"
type DefaultAuthorizer ¶
type DefaultAuthorizer struct {
// contains filtered or unexported fields
}
func NewDefaultAuthorizer ¶
func NewDefaultAuthorizer(application string, opts ...Option) *DefaultAuthorizer
func (*DefaultAuthorizer) AffirmAuthorization ¶
func (a *DefaultAuthorizer) AffirmAuthorization(ctx context.Context, fullMethod string, grpcReq interface{}) (context.Context, error)
AffirmAuthorization makes an authz request to sidecar-OPA. If authorization is permitted, error returned is nil, and a new context is returned, possibly containing obligations. Caller must further evaluate obligations if required.
func (*DefaultAuthorizer) Evaluate ¶
func (a *DefaultAuthorizer) Evaluate(ctx context.Context, fullMethod string, grpcReq interface{}, opaEvaluator OpaEvaluator) (bool, context.Context, error)
func (*DefaultAuthorizer) FilterCompartmentFeatures ¶ added in v0.0.13
func (a *DefaultAuthorizer) FilterCompartmentFeatures(ctx context.Context, features FilterCompartmentFeaturesType) (FilterCompartmentFeaturesType, error)
FilterCompartmentFeatures filters list of features based on the JWT in the context
func (*DefaultAuthorizer) FilterCompartmentPermissions ¶ added in v0.0.13
func (a *DefaultAuthorizer) FilterCompartmentPermissions(ctx context.Context, permissions FilterCompartmentPermissionsType) (FilterCompartmentPermissionsType, error)
FilterCompartmentPermissions filters list of permissions based on the JWT in the context
func (*DefaultAuthorizer) GetAcctEntitlements ¶ added in v0.0.7
func (a *DefaultAuthorizer) GetAcctEntitlements(ctx context.Context, accountIDs, serviceNames []string) (*AcctEntitlementsType, error)
GetAcctEntitlements queries account entitled features data for the specified account-ids and entitled-services. If both account-ids and entitled-services are empty, then data for all entitled-services in all accounts are returned.
func (*DefaultAuthorizer) GetAcctEntitlementsBytes ¶ added in v0.0.7
func (a *DefaultAuthorizer) GetAcctEntitlementsBytes(ctx context.Context, accountIDs, serviceNames []string) ([]byte, error)
GetAcctEntitlementsBytes queries account entitled features data for the specified account-ids and entitled-services. If both account-ids and entitled-services are empty, then data for all entitled-services in all accounts are returned. Returns the raw JSON string response
func (*DefaultAuthorizer) GetCurrentUserCompartments ¶ added in v0.0.13
func (a *DefaultAuthorizer) GetCurrentUserCompartments(ctx context.Context) ([]string, error)
GetCurrentUserCompartments returns list of compartment-ids for the current-user's JWT in the context.
func (*DefaultAuthorizer) OpaQuery ¶
func (a *DefaultAuthorizer) OpaQuery(ctx context.Context, decisionDocument string, opaReq, opaResp interface{}) error
func (DefaultAuthorizer) String ¶ added in v0.0.3
func (a DefaultAuthorizer) String() string
func (*DefaultAuthorizer) Validate ¶ added in v0.0.14
func (a *DefaultAuthorizer) Validate(ctx context.Context, fullMethod string, grpcReq interface{}, opaEvaluator OpaEvaluator) (interface{}, error)
type DefaultDecisionInputer ¶
type DefaultDecisionInputer struct{}
DefaultDecisionInputer is an example DecisionInputHandler that is used as default
func (*DefaultDecisionInputer) GetDecisionInput ¶
func (m *DefaultDecisionInputer) GetDecisionInput(ctx context.Context, fullMethod string, grpcReq interface{}) (*DecisionInput, error)
GetDecisionInput is an example DecisionInputHandler that returns some decision input based on some incoming Context values. App/services will most likely supply their own DecisionInputHandler using WithDecisionInputHandler option.
func (DefaultDecisionInputer) String ¶ added in v0.0.3
func (m DefaultDecisionInputer) String() string
type EntitledFeaturesKeyType ¶ added in v0.0.5
type EntitledFeaturesKeyType string
EntitledFeaturesKeyType is the type of the entitled_features key stored in the caller's context
type FilterCompartmentFeaturesInput ¶ added in v0.0.13
type FilterCompartmentFeaturesInput struct { JWT string `json:"jwt"` ApplicationFeatures FilterCompartmentFeaturesType `json:"application_features"` }
FilterCompartmentFeaturesInput is the input payload for filter_compartment_features_api
type FilterCompartmentFeaturesResult ¶ added in v0.0.13
type FilterCompartmentFeaturesResult struct {
Result FilterCompartmentFeaturesType `json:"result"`
}
FilterCompartmentFeaturesResult is the data type json.Unmarshaled from OPA RESTAPI query to filter_compartment_features_api rego rule
type FilterCompartmentFeaturesType ¶ added in v0.0.13
FilterCompartmentFeaturesType is a convenience data type, returned by FilterCompartmentFeatures() (map of application to array of feature)
type FilterCompartmentPermissionsInput ¶ added in v0.0.13
type FilterCompartmentPermissionsInput struct { JWT string `json:"jwt"` Permissions FilterCompartmentPermissionsType `json:"permissions"` }
FilterCompartmentPermissionsInput is the input payload for filter_compartment_permissions_api
type FilterCompartmentPermissionsResult ¶ added in v0.0.13
type FilterCompartmentPermissionsResult struct {
Result FilterCompartmentPermissionsType `json:"result"`
}
FilterCompartmentPermissionsResult is the data type json.Unmarshaled from OPA RESTAPI query to filter_compartment_permissions_api rego rule
type FilterCompartmentPermissionsType ¶ added in v0.0.13
type FilterCompartmentPermissionsType []string
FilterCompartmentPermissionsType is a convenience data type, returned by FilterCompartmentPermissions() (map of application to array of permissions)
type OPARequest ¶
type OPARequest struct {
// OPA expects field called "input" to contain input payload
Input interface{} `json:"input"`
}
OPARequest is used to query OPA
type OPAResponse ¶
type OPAResponse map[string]interface{}
OPAResponse unmarshals the response from OPA into a generic untyped structure
func (OPAResponse) AddRawEntitledFeatures ¶ added in v0.0.5
func (o OPAResponse) AddRawEntitledFeatures(ctx context.Context) context.Context
AddRawEntitledFeatures adds raw entitled_features (if they exist) from OPAResponse to context The raw JSON-unmarshaled entitled_features is of the form:
map[string]interface {}{"lic":[]interface {}{"dhcp", "ipam"}, "rpz":[]interface {}{"bogon", "malware"}}}
func (OPAResponse) Obligations ¶
func (o OPAResponse) Obligations() (*ObligationsNode, error)
Obligations parses the returned obligations and returns them in standard format
type ObligationKey ¶
type ObligationKey string
type ObligationsEnum ¶
type ObligationsEnum int
ObligationsEnum enumerates the different kinds of ObligationsNode
const ( ObligationsEmpty ObligationsEnum = iota // Default "zero" value for uninitialized ObligationsEnum ObligationsCondition ObligationsAnd ObligationsOr )
The different kinds of ObligationsNode
func (ObligationsEnum) String ¶
func (o8e ObligationsEnum) String() string
String implements fmt.Stringer interface
type ObligationsNode ¶
type ObligationsNode struct { Kind ObligationsEnum Tag string Condition string Children []*ObligationsNode }
ObligationsNode defines the generic obligations tree returned by middleware in the context
func (*ObligationsNode) DeepSort ¶
func (o8n *ObligationsNode) DeepSort()
DeepSort recursively sorts any nested nodes. Intended to be used in unit-tests to force deterministic order for comparison.
func (*ObligationsNode) IsShallowEmpty ¶ added in v0.0.2
func (o8n *ObligationsNode) IsShallowEmpty() bool
IsShallowEmpty returns whether this node is empty (has no obligations).
func (*ObligationsNode) ShallowLength ¶
func (o8n *ObligationsNode) ShallowLength() int
ShallowLength returns the length of this node. It does not include the lengths of any nested nodes. Length zero means this node is empty (has no obligation).
func (*ObligationsNode) ShallowLessThan ¶
func (lhs *ObligationsNode) ShallowLessThan(rhs *ObligationsNode) bool
ShallowLessThan returns true if lhs less than rhs. Does not consider nested nodes. Intended for use by DeepSort method.
func (*ObligationsNode) String ¶
func (o8n *ObligationsNode) String() string
String() returns a multiline pretty string representation (actually JSON), intended to be human-readable for debugging purposes.
func (*ObligationsNode) ToSQLPredicate ¶ added in v0.0.2
func (o8n *ObligationsNode) ToSQLPredicate(sqlc *sqlcompiler.SQLCompiler) (string, error)
ToSQLPredicate recursively converts obligations node tree into SQL predicate
type OpaEvaluator ¶
type OpaEvaluator func(ctx context.Context, decisionDocument string, opaReq, opaResp interface{}) error
OpaEvaluator implements calling OPA with a request and receiving the raw response
type Option ¶
type Option func(c *Config)
func WithAcctEntitlementsApiPath ¶ added in v0.0.7
WithAcctEntitlementsApiPath overrides default AcctEntitlementsApiPath
func WithAuthorizer ¶
func WithAuthorizer(auther ...Authorizer) Option
WithAuthorizer overrides the request/response processing of OPA. Multiple authorizers can be passed
func WithClaimsVerifier ¶ added in v0.0.3
func WithClaimsVerifier(claimsVerifier ClaimsVerifier) Option
WithClaimsVerifier overrides default ClaimsVerifier
func WithDecisionInputHandler ¶
func WithDecisionInputHandler(decisionHandler DecisionInputHandler) Option
WithDecisionInputHandler supplies optional DecisionInputHandler for DefaultAuthorizer to obtain additional input for OPA ABAC decision processing.
func WithEntitledServices ¶ added in v0.0.5
WithEntitledServices overrides default EntitledServices
func WithFilterComparmentFeaturesApiPath ¶ added in v0.0.13
WithFilterComparmentFeaturesApiPath overrides default CurrentUserCompartmentsApiPath
func WithFilterComparmentPermissionsApiPath ¶ added in v0.0.13
WithFilterComparmentPermissionsApiPath overrides default CurrentUserCompartmentsApiPath
func WithHTTPClient ¶
WithHTTPClient overrides the http.Client used to call Opa
func WithOpaClienter ¶ added in v0.0.3
func WithOpaClienter(clienter opa_client.Clienter) Option
WithOpaClienter overrides the Clienter used to call Opa. This option takes precedence over WithHTTPClient.
func WithOpaEvaluator ¶
func WithOpaEvaluator(opaEvaluator OpaEvaluator) Option
WithOpaEvaluator overrides the OpaEvaluator use to evaluate authorization against OPA.
type Payload ¶
type Payload struct { Endpoint string `json:"endpoint"` Application string `json:"application"` // FullMethod is the full RPC method string, i.e., /package.service/method. FullMethod string `json:"full_method"` JWT string `json:"jwt"` RequestID string `json:"request_id"` EntitledServices []string `json:"entitled_services"` DecisionInput }
type WrappedSrvStream ¶
type WrappedSrvStream struct { grpc.ServerStream // It is wrapper's own Context. WrappedCtx context.Context }
WrappedSrvStream allows modifying context.
func (*WrappedSrvStream) Context ¶
func (w *WrappedSrvStream) Context() context.Context
Context returns the wrapper's WrappedCtx