App Gateways
AppGateways control user access to apps by providing declarative tools for proxies and connectors. AppGateways proxy apps, and can determine which identity systems should be used to authenticate and authorize users. They may also be used to extend those identity systems by managing sessions or by mapping attributes or claims to specific
headers
which legacy apps need to allow access. AppGateways can also use attrProviders
to obtain additional data which can be used to evaluate policy.As a security measure, the orchestrator does not forward Maverics cookies to upstream apps.
The
name
value is a unique identifier for each AppGateway.The
basePath
defines the path prefix that the AppGateway will listen for requests on. For example, a basePath
of /foo
means that the AppGateway will listen for all requests that are made with a prefix of /foo
, such as /foo/index.html
.host
is an optional field used to route requests to the correct AppGateway when the basePath
s of one or more AppGateways conflict. For instance, two applications may have a basePath
of /
and therefore need a host
value specified to enable correct routing.appgateways:
- name: alpha
basePath: /
host: alpha.com
- name: beta
basePath: /
host: beta.com
upstream
is the URL of app that is being protected and proxied to. This could be an IP address or hostname, and port that the application listens on.preserveHost
is an optional boolean field used to determine if the Host
header should be preserved on outbound requests. By default, the orchestrator will set the host header to match the upstream
's host. This field is often used when the orchestrator is forwarding traffic to another reverse proxy such as Apache.The
tls
field is used to specify the TLS configuration for outbound requests to the upstream
. The value must reference a TLS object defined in the top-level TLS configuration. This field is optional, and is typically used when the upstream
target uses certificates signed by an unknown certificate authority.rewrites
are used to replace URLs on the request and on the response. This can be handy when proxying to an application that uses absolute URLs. This feature should be used with caution as it will impact the performance of an AppGateway.appgateways:
- name: rewritesExample
basePath: /
rewrites:
# The URL on the left side of the colon is replaced with the URL on the right.
https://app-internal.example.com: https://app.example.com
attrProviders
represent the identity system or data store from which an AppGateway retrieves additional attributes required for evaluating policies
and building headers
.appgateways:
- name: exampleAttrProvider
basePath: /
attrProviders:
- connector: ldap
usernameMapping: azure.mail
- connector: mysql
usernameMapping: azure.mail
Specifies the attribute to use as a lookup key in order to load attributes from the attribute provider. The value usually comes from the IDP that was used for primary authentication, for example,
azure.sub
.AppGateways often protect applications that require an external identity provider to authenticate the user and set values in HTTP
headers
before allowing access. Headers are configured as a mapping key value pairs where the key is header's name and the value is the header's value. The values are declared using a namespace such as azure.sub
.appgateways:
- name: exampleHeaders
basePath: /
headers:
SM_USER: azure.sub
firstName: ldap.givenName
lastName: ldap.sn
Custom headers can be created by using the
createHeader
Service Extension. For more info, please see the Create Header Service Extension docs.policies
determine whether a given request should be allowed, ultimately defining which users are allowed application access. If no policies are defined in the AppGateway config, it will deny all requests.AppGateways use
authentication
and authorization
to evaluate whether a user should be allowed to access an application location
. These policies extend the native authentication and authorization policies of the connected identity system(s). The user is allowed to access if they meet configured conditions: such as having been authenticated by the idp
, or carrying attributes that may indicate membership in a group or some other aspect of the user that is evaluated in policy.A policy
location
is used to map an application resource to a policy. The AppGateway will match a request to the most specific location
. The ordering in config of policy locations does not matter.appgateways:
- name: examplePolicy
basePath: /
policies:
- location: /index.html
authentication:
allowUnauthenticated: true
authorization:
allowAll: true
To apply Regular Expression matching to resource path, add
~
(note the space) at the front of the location
. You can use tools such as regex101 (choose Golang) to test your regex against URL paths you would like to match. For example, to match any resource that starts with myresource
:appgateways:
- name: examplePolicyWithRegex
basePath: /
policies:
- location: ~ ^/myresource.*
authentication:
allowUnauthenticated: true
authorization:
allowAll: true
Notice the
^
to ensure the regex matches only at the beginning of the resource path. The orchestrator automatically escapes /
characters in the URL path, so do not escape these manually (e.g. ^\/
).Poorly constructed regexes can impact orchestrator performance. Use anchors (
^
or $
) where possible, and counters or ranges (.{0,15}
) instead of "greedy" wildcards (.*
).useQueryParamsForMatchingPolicy
is used to match requests with query parameters to the correct policy. Query parameter matching only works with locations that use regex matching (i.e. preceded with a ~
).In order to match URLs which include query parameters such as the URL
https://mydomain.com/myresource/?param=abcd
, you would define a policy similar to:appgateways:
- name: examplePolicyWithQueryParams
basePath: /
policies:
- location: ~ ^/myresource/\?param=abcd
useQueryParamsForMatchingPolicy: true
authentication:
allowUnauthenticated: true
authorization:
allowAll: true
For multiple query parameters with consistent ordering:
appgateways:
- name: examplePolicyWithQueryParams
basePath: /
policies:
- location: ~ ^/myresource/\?param=abc&code=def
useQueryParamsForMatchingPolicy: true
authentication:
allowUnauthenticated: true
authorization:
allowAll: true
If the query parameters could appear in either order, with other params between them:
appgateways:
- name: examplePolicyWithQueryParams
basePath: /
policies:
- location: ~ ^/myresource/\?.{0,15}(param=abc|code=def){1}.{0,15}\&(param=abc|code=def){1}
useQueryParamsForMatchingPolicy: true
authentication:
allowUnauthenticated: true
authorization:
allowAll: true
authentication
declares a location's authentication policy. When an unauthenticated request for a resource is received, a default authentication policy will handle the unauthenticated request and redirect a user to an IDP or MFA provider for login as needed.Example using Azure for authentication:
appgateways:
- name: exampleAuthnPolicy
basePath: /
policies:
- location: /sonar
authentication:
idps:
- azure
authorization:
allowAll: true
Example using Azure for primary authentication and PingOne for MFA:
include:
- "/etc/maverics/configs/connectors/azure.yaml"
- "/etc/maverics/configs/connectors/pingone.yaml"
appgateways:
- name: exampleAuthnMFAPolicy
basePath: /
policies:
- location: /sonar
authentication:
idps:
- azure
mfa:
- pingone:
mapping:
- email: azure.email
idps
take a list of one or more IDP connector names to use for authentication.mfa
takes a list of one or more MFA (multi-factor authentication) connector names. Under each connector, a mapping
section is required to define how an MFA identity is mapped to the corresponding IDP identity.The
mapping
field supports the keywords and
, or
and not
to express complex evaluations. If the names are a YAML list with no keywords they will be evaluated with an implicit and
.The
allowUnauthenticated
operator can be used to allow open access to a resource. If set to true
, the resource for this policy does not require any authentication. This operator is typically, used is for resources like error or login pages.The
authorization
operator declares a location's authorization policy and enables the formation of arbitrarily complex policies. The authorization operator can be used in conjunction with the all, any, equal, and contains operators. If unspecified, access to the location is denied. The authorization
section can use the evaluators detailed below
to construct authorization policy.Example with simple authorization policy:
appgateways:
- name: exampleAuthzPolicy
basePath: /
policies:
- location: /
authentication:
idps:
- azure
authorization:
- or:
- contains: ["{{azure.groups}}", "admins"]
- contains: ["{{azure.groups}}", "executives"]
The
allowAll
operator (allowAll: true
) authorizes all users for a location. This must be set explicitly for each location to be accessible to all users and should not be used in combination with any other policy rules for a location.All conditions/operators defined in an
and
block need to evaluate to true
for the policy to evaluate to true
.Any of the conditions/operators defined in an
or
block need to evaluate to true
for the policy to evaluate to true
.Any condition or operator defined in a
not
block evaluates to the inverse. If the condition in the not
policy is true
, the policy will be evaluated to false
and vice-versa. To evaluate a list of conditions with not
, you must nest the conditions in an or
or and
block.Containscontains
requires two strings, normally an attribute from the session and a value to compare it to, and returns true if the second string matches any part of the first (i.e. a substring match). Values from the user's session can be included in the policy evaluation by enclosing them in double curly braces. For example,contains: ["{{azure.name}}", "@example.com"]
.
EqualsEvaluates to true if the two values areequal
when the policy is run.
headers
define the set of headers for a specific location. These headers will override headers
of the same name that are defined at the AppGateway level. The createHeader
Service Extension may be used at this level as well.This sample configuration defines headers at the policy level to include headers for a specific location. It also overrides the headers at the AppGateway level.
appgateways:
- name: Sonar
basePath: /
headers:
SM_USER: azure.username
firstname: azure.givenName
lastname: azure.surname
policies:
- location: /
authentication:
idps:
- azure
headers:
# Override 'firstname' header defined in 'headers'.
firstname: azure.preferred_username
- location: /admin
authentication:
idps:
- azure
headers:
# Add new header for /admin location.
IS_ADMIN: azure.isAdmin
The
errorPage
is the URL a user is redirected when an error occurs.The
unauthorizedPage
is the URL a user is redirected when a policy evaluation denies access to the app.AppGateways use Service Extensions to enable custom logic that is not natively supported. Service Extensions can be used to load attributes, extend authentication and authorization policy evaluations, and create headers.
Although Maverics supplies an abundance of connectors to use for user authentication, some organizations want to customize the authentication experience or may have needs not expressed in existing connectors. The Authentication Service Extensions allow administrators to define the authentication process in exactly the manner they need.
Loading attributes about a user's session is also customizable via Service Extensions.
Service Extensions also give complete control over access to protected resources via authorization.
It can be useful to determine if a request to an upstream application is authenticated and to be able to login to an upstream app.
Certain situations require the ability to modify every request and response that flows through the AppGateway's proxy.
Gain finer control over how a request is handled in an AppGateway.
This sample base YAML config declares:
- An app called "Sonar"
- A location on the app that is protected
- That a session must be present and validated in order for the user to access the app
- A connected Azure AD tenant as the identity provider for the user
- The attribute mappings from the Azure AD claims to HTTP headers
- A policy that allows access to the app when the user is authenticated to Azure
- A policy that allows access to a specific location only when the user's data meets specific criteria
version: 0.1
tls:
maverics:
certFile: certs/example-strata.crt
keyFile: certs/example-strata.key
http:
address: :443
tls: maverics
include:
- "/etc/maverics/configs/connectors/azure.yaml"
idps:
- name: azure
appgateways:
- name: Sonar
basePath: /
host: app.sonarsystems.com
upstream: https://example.com:8080
errorPage: https://app.sonarsystems.com/sonar/error
unauthorizedPage: https://app.sonarsystems.com/sonar/accessdenied
headers:
SM_USER: azure.username
firstname: azure.givenName
lastname: azure.surname
policies:
- location: /
authentication:
idps:
- azure
- location: /sonar/accessdenied
authentication:
allowUnauthenticated: true
authorization:
allowAll: true
- location: /sonar/execs
authentication:
idps:
- azure
authorization:
- or:
- contains: ["{{azure.email}}", "@sonarsystems.com"]
- contains: ["{{azure.email}}", "@example.com"]
In the
authentication
section, you will find one IDP and one MFA defined. The default authentication flow will have user authenticate with azure
connector followed with the specified MFA (Multi-Factor Authentication) provider under the mfa
section. In this example, the config is shown using pingone
as the connector for the MFA provider. The mapping here is expressed as two different conditions in a scenario where some users are mapped to the email
attribute and other users are mapped to the userid
attribute for the same pingone
connector. If the user doesn't have the email
attribute on their session, then the default authentication flow will try to authenticate the user to the pingone
connector using the userid
attribute....
include:
- "/etc/maverics/configs/connectors/azure.yaml"
- "/etc/maverics/configs/connectors/pingone.yaml"
appgateways:
- name: Sonar
# ...
policies:
- location: /sonar
authentication:
idps:
- azure
mfa:
- pingone:
mapping:
- or:
- email: azure.email
- userid: azure.userid
In the config below, the
and
operator is used to indicate a mapping of two fields are desired....
include:
- "/etc/maverics/configs/connectors/azure.yaml"
- "/etc/maverics/configs/connectors/pingone.yaml"
appgateways:
- name: Sonar
# ...
policies:
- location: /sonar
authentication:
idps:
- azure
mfa:
- pingone:
mapping:
- and:
- email: azure.email
- tenantID: azure.group
This config demonstrates a more advanced and complex scenario where it can be expressed with multiple operators.
...
include:
- "/etc/maverics/configs/connectors/azure.yaml"
- "/etc/maverics/configs/connectors/pingone.yaml"
appgateways:
- name: Sonar
# ...
policies:
- location: /sonar
authentication:
idps:
- azure
mfa:
- pingone:
mapping:
- or:
- and:
- email: azure.email
- tenantID: azure.group
- email: azure.email
This config demonstrates a mapping expressed with the
not
operator where if the attribute azure.custom
exists on the session, then map user to pingone
using the secondary email....
include:
- "/etc/maverics/configs/connectors/azure.yaml"
- "/etc/maverics/configs/connectors/pingone.yaml"
appgateways:
- name: Sonar
# ...
policies:
- location: /sonar
authentication:
idps:
- azure
mfa:
- pingone:
mapping:
- or:
- and:
- email: azure.verified_primary_email
- not:
custom: azure.custom
- email: azure.verified_secondary_email
The AppGateway uses
authorization
to protect resources, returning 403 Forbidden when trying to access the resource if the policy does not evaluate to true.In this sample configuration, the AppGateway uses
authorization
to enable access to /sonar/reports
for certain users. If user's email contains the strata.io
domain, access is enabled for users with the names Marie
, Ivan
, and Ludwig
. If user email contains the sonarsystems.com
domain, access is enabled for users with the names Donna
, Jacob
, and Rufus
....
include:
- "/etc/maverics/configs/connectors/azure.yaml"
idps:
- name: azure
appgateways:
- name: Sonar
# ...
policies:
- location: /sonar
authentication:
idps:
- azure
authorization:
allowAll: true
- location: /sonar/reports
authentication:
idps:
- azure
authorization:
- and:
- equal: [ "{{azure.custom}}", "expected" ]
- or:
- and:
- contains: [ "{{azure.name}}", "@strata.io" ]
- or:
- equal: [ "{{azure.givenname}}", "Marie" ]
- equal: [ "{{azure.givenname}}", "Ivan" ]
- equal: [ "{{azure.givenname}}", "Ludwig" ]
- and:
- contains: [ "{{azure.name}}", "@sonarsystems.com" ]
- or:
- equal: [ "{{azure.givenname}}", "Donna" ]
- equal: [ "{{azure.givenname}}", "Jacob" ]
- equal: [ "{{azure.givenname}}", "Rufus" ]
This sample configuration uses an LDAP Connector instance to fetch additional information about users. When the additional attributes are loaded, Maverics will perform an authorization check against the loaded attributes before granting access to the user.
include:
- "/etc/maverics/configs/connectors/azure.yaml"
idps:
- name: azure
connectors:
- name: ldap
type: ldap
url: "ldap://ldap.example.com:389"
serviceAccountPassword: <PASSWORD>
serviceAccountUsername: cn=admin,dc=example,dc=com
baseDN: ou=People,dc=example,dc=com
usernameSearchKey: mail
appgateways:
- name: Sonar
# ...
attrProviders:
- connector: ldap
usernameMapping: azure.emailaddress
policies:
- location: /sonar
loadAttrsSE:
funcName: LoadAttrs
file: /etc/maverics/extensions/loadAttrs.go
authentication:
idps:
- azure
authorization:
- equal: [ "{{ldap.department}}", "Accounting" ]
Last modified 2mo ago