App gateways (Legacy)
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.
Name
The name
value is a unique identifier for each AppGateway.
Base Path
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
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
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.
Preserve Host
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.
TLS
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
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
Attribute Providers
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
Connector
connector
references the connector that will be used to
load attributes.
Username Mapping
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
.
Headers
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
Create Header Service Extension
Custom headers can be created by using the createHeader
Service Extension. For more
info, please see the Create Header Service Extension
docs.
Policies
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.
Location
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 (.*
).
Query Param Matching
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
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
idps
take a list of one or more IDP connector names to use for authentication.
MFA
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
.
Allow Unauthenticated Access
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.
Authorization
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"]
Allow All
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.
And
All conditions/operators defined in an and
block need to evaluate to true
for
the policy to evaluate to true
.
Or
Any of the conditions/operators defined in an or
block need to evaluate to true
for the policy to evaluate to true
.
Not
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.
Contains
contains
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"]
.
Equals
Evaluates to true if the two values are
equal
when the policy is run.
Headers
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
Error Page
The errorPage
is the URL a user is redirected when an error occurs.
Unauthorized Page
The unauthorizedPage
is the URL a user is redirected when a policy evaluation
denies access to the app.
Service Extensions
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.
Authentication
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.
Details at [Authentication Service Extensions](service-extension-authentication.
Loading Attributes
Loading attributes about a user’s session is also customizable via Service Extensions.
Details at Loading Attributes via Service Extension.
Authorization
Service Extensions also give complete control over access to protected resources via authorization.
Details at Authorization via Service Extension.
Upstream Login
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.
Details at Upstream Application Login.
Request and Response Modification
Certain situations require the ability to modify every request and response that flows through the AppGateway’s proxy.
Details at Request & Response Modification Service Extension
Overriding Default AppGateway Request Flow
Gain finer control over how a request is handled in an AppGateway.
Details at Serve Service Extension
Examples
Base
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"
appgateways:
- name: Sonar
basePath: /
host: app.sonarsystems.com
upstream: https://example.com:8443
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"]
Authentication Policy
Authentication flow with MFA mapping using logical operators
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
Authorization Policy
The AppGateway uses authorization
to protect resources, returning 403 Forbidden
when trying to access the resource if the policy does not evaluate to true.
Policy using authorization
with nested conditions
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"
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" ]
Policy using Attributes from LDAP
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"
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" ]