Go to new doc!

+49 228 5552576-0


info@predic8.com

Simple file based access control with API Keys

The simplest way to secure an API with keys is the file based setup described in this document. Access control based on API keys is a subset of the API Management features of Membrane Service Proxy. For a full blown API Management solution with developer and user dashboard please follow to the API Management Github page.

A file that is loaded on startup specifies policies and API keys. The file can be edited manually or e.g. you could generate it out of your users database.

Example: File based Access Control with API Keys using Membrane

Membrane comes with a preconfigured simple API keys example that is ready to run. In this example we will send requests to a service with and without an API key. Go to the $MEMBRANE_HOME/examples/api-management/simple-file-based folder. See and follow the steps in the README.txt.

Example details

This example consists of 2 parts. At first you will have a look at the policy file and see how to configure policies and create API keys that use these policies. The second part takes a look at the Membrane configuration on how to set up API Management with Membrane.

The Policy File

Have a look at the api.yaml in the example folder.

        policies:
          - policy:
              id: "TrialAppX"
              serviceProxy:
                - "Names API"
          - policy:
              id: "Customer"
              rateLimit:
                requests: '1000'
                interval: '3600'
              serviceProxy:
                - "Web Page"
                - "Names API"

        keys:
          - key: "abcdefg"
            expires: "2020-01-01T12:00:00"
            policies:
              - "TrialAppX"
              - "Customer"
          - key: "gfedcba"
            policies:
              - "TrialAppX"
      
Listing 1: The policy configuration in api.yaml

The configuration is defined in YAML and split in policies and keys.

The first part of the YAML configuration defines a list of policies. A policy defines rules for a list of services. The policy object has several attributes you can define.

Policy object
Attribute Description Default Type
id The name of the policy --- String
rateLimit (optional)
  • requests (Integer): The number of requests allowed in an interval before blocking
  • interval (Integer): Time after counted requests are reset; Integer
1000 requests per 3600 seconds Object
quota (optional)
  • size (String): traffic that is allowed to pass through before blocking. It is specified as a number with size unit suffix, e.g. 100b, 250kb, 50mb, 1gb
  • interval (Integer): Time in seconds until the counted size is reset
1mb per 86400 seconds (1 day) Object
unauthenticated (optional) A policy can be unauthenticated. It then also works when no API key is specified (but doesn't work with wrong API keys) false Boolean
serviceProxy A list of serviceProxies to which this policy applies --- List of Strings

Note: ratelimit and quota are objects

To use the default values just leave out the attributes you want defaults for.

A service can be covered by multiple policies. The API key decides what policy should be in effect.

The second part of the YAML configuration defines a list of keys. A key defines a list of policies that authorizes the client to use some services. The key object has several attributes you can define.

Key object
Attribute Description Type
key The API key --- String
expiration (optional) The expiration date in ISO 8601 format with trailing "Z" never expire String
policies The list of policies this API key is usable with --- List of Strings

To use the default values just leave out the attributes you want defaults for.

API keys can have multiple policies and those policies can have overlapping services. When such a service is used all rules apply simultaneously, e.g. 2 policies define the "Names API" service and both have a rateLimit and quota then both rateLimits and quotas are in effect.

Membrane Configuration

Have a look at the proxies.xml in the example folder.

    <!-- <simpleApiConfig> - this bean is implicitly here when no other api configurator is specified.
		 In this example we use the file base api management-->
	<router>

		<!-- To use API Management one has to explicitly specifiy the transport chain of Membrane-->
		<transport>
			<ruleMatching />
			<exchangeStore />
			<dispatching />

			<!-- API Management is activated by putting it in the transport chain between dispatching and reverseProxying -->
			<apiManagement>
				<!-- API Management currently has 2 interceptors, a rate limiter and quota ( bandwidth limiter ) -->
				<amRateLimiter/>
				<amQuota/>
			</apiManagement>

			<reverseProxying />
			<userFeature />
			<httpClient />
		</transport>


		<!-- API Management works with service proxy names. Thus the name attribute needs to be defined -->
		<serviceProxy port="8080" name="Web Page">
			<target host="www.thomas-bayer.com" port="80"/>
		</serviceProxy>

		<serviceProxy port="8081" name="Names API">
			<path>/restnames</path>
			<target host="www.thomas-bayer.com" port="80"/>
		</serviceProxy>

		<!-- Admin console can always be accessed without an API key so in production environments they have to be secured, e.g. by basic authentication -->
		<serviceProxy port="9000" name="AdminConsole">
			<adminConsole/>
		</serviceProxy>


	</router>
      
Listing 2: Membrane configuration in proxies.xml

In this example we use the file based API Management. This works as default when using API Management. This behaviour can be changed by specifying another bean before the router element, e.g. <etcdRegistryApiConfig>. You can also explicitly define the file based approach by using the <simpleApiConfig> bean.

API Management is part of Membranes transport chain. Here you can add the optional rate limit and quota interceptors.

By default the HeaderKeyRetriever is used that takes the API key from the http authorization header field.

There is also the possibility to collect statistics about requests processed by API Management. For this to work you can add the <amStatisticsCollector> as last interceptor in the apiManagement element. These statistics are then collected in an elastic search instance that you can specify through the attributes of the amStatisticsCollector element.

amStatisticsCollector attributes
Attribute Description
host Host of the elastic search instance
clientId Client id for basic authentication
clientSecret Client secret for basic authentication

Services, for API Management, are defined by specifying the name attribute of serviceProxies. These names are the ones used in the policy file.

Admin consoles are a special case of service. They are always reachable through API Management even when not using an API key. They need to be protected from external access, e.g. by using the basic authentication interceptor of Membrane.

Help needed?

Do you need any help for this example? Then contact us using the Membrane Google Group or send an email to membrane@predic8.com.