Configuration
Tilegroxy is a configuration driven application. This documentation describes the various configuration options available. Configuration can be supplied as either YAML or JSON format. Documentation is primarily in YAML format however advanced YAML features are avoided to make it easy to convert to JSON.
Conventions
Parameter names (configuration keys) are case-insensitive unless indicated otherwise.
Names (see below) are always lower case.
Some parameters can be specified by environment variables which must be upper case. Environment variables override config parameters which override default values.
Entities
Some configuration sections (authentication, provider, cache, datastores and secret) support selecting different methods of operation that change the full list of parameters available. For example, a "proxy" provider requires a url
parameter to get a map tile from another server while a "static" provider takes in a image
to return for every request. You select these operating modes using a parameter called name
.
Since these entities are too dynamic to have fixed environment variables and frequently may require a secret to operate, any string parameters can be made to use an environment variable by specifying a value in the format of env.ENV_VAR_NAME
. You can also use an external secret store if configured by specifying a value in the format secret.SECRET_NAME
Structure
The following is the top-level configuration structure. All top-level keys are optional besides layers:
server: …
client: …
logging: …
telemetry: …
error: …
secret: …
authentication: …
cache: …
datastores:
- …
layers:
- …
Layer
A layer represents a distinct mapping layer as would be displayed in a typical web map application. Each layer can be accessed independently from other map layers. The main thing that needs to be configured for a layer is the provider described below.
The URLs of incoming requests follow a format like: /tiles/{layerName}/{z}/{x}/{y}
the layer name can be one of two things: 1) the ID of the layer or 2) A string that matches a pattern. A pattern should include non-subsequent placeholder values wrapped in curly braces. Those placeholder values can be used in certain providers, such as the Proxy provider where they can be forwarded along to the upstream map layer. To understand how you can utilize patterns, see the NOAA Post-Storm example
When using a pattern you can include Regular Expressions to validate the values that match against the placeholder.
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
id |
A url-safe identifier of the layer. Primarily used as the default path for incoming tile web requests |
string |
Yes |
None |
pattern |
A url-safe pattern with non-subsequent placeholders |
string |
No |
id |
paramValidator |
A mapping of regular expressions to use to validate the values that match against the placeholders. The regular expressions must match the full value. Specify a key of "*" to apply it to all values |
map[string]string |
No |
None |
provider |
The configuration that drives how tiles are generated |
Yes |
None |
|
client |
A Client configuration to use for this layer specifically that overrides the Client from the top-level of the configuration. See below for Client schema |
No |
None |
|
skipcache |
If true, skip reading and writing to cache |
bool |
No |
false |
Example:
layer: id: my_layer pattern: my_{name}_{version} paramValidator: "*": "^[a-zA-Z0-9]+$" "version": "v[0-9]{1,3}" skipCache: true client: userAgent: my_app/1.0 provider: ...
Provider
A provider represents the underlying functionality that "provides" the tiles that make up the mapping layer. This is most commonly an external HTTP(s) endpoint using either the "proxy" or "URL template" providers. Custom providers can be created to extract tiles from other sources.
When supplying a provider ensure you include the name
parameter. Some providers require nested providers; be aware that repeated nesting has a performance cost.
Proxy
The Proxy provider is the simplest option that simply forwards tile requests to another HTTP(s) endpoint. This provider can be used for mapping services that operate in tiles (ZXY, TMS, or WMTS) or against bounds (i.e. WMS). TMS inverts the y coordinate compared to ZXY and WMTS formats, which is handled by the InvertY parameter.
The following is the typical request flow when using a proxy provider:

Name should be "proxy"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
url |
A URL pointing to the tile server. Should contain placeholders surrounded by "{}" that are replaced on-the-fly |
string |
Yes |
None |
inverty |
Changes Y tile numbering to be South-to-North instead of North-to-South. Only impacts Y/y placeholder |
bool |
No |
false |
srid |
What projection bounds should be in. Can only be 4326 or 3857 |
uint |
No |
4326 |
The following placeholders are available in the URL:
Placeholder | Description |
---|---|
x or X |
The X tile coordinate from the incoming request |
y or Y |
The Y tile coordinate either from the incoming request or the "flipped" equivalent if the |
z or Z |
The Z tile coordinate from the incoming request (aka "zoom") |
xmin |
The "west" coordinate of the bounding box defined by the incoming tile coordinates. In the projection specified by |
xmax |
The "east" coordinate of the bounding box defined by the incoming tile coordinates. In the projection specified by |
ymin |
The "north" coordinate of the bounding box defined by the incoming tile coordinates. In the projection specified by |
ymax |
The "south" coordinate of the bounding box defined by the incoming tile coordinates. In the projection specified by |
env.XXX |
An environment variable whose name is XXX |
ctx.XXX |
A context variable (typically an HTTP header) whose name is XXX |
layer.XXX |
If the layer includes a pattern with a placeholder of XXX, this is the replacement value from the used layer name |
Example:
provider: name: proxy url: https://tile.openstreetmap.org/{z}/{x}/{y}.png?key={env.key}&agent={ctx.User-Agent}
URL Template
The URL Template provider overlaps with the Proxy provider but is meant specifically for WMS endpoints. Instead of merely supplying tile coordinates, the URL Template provider will supply the bounding box. This provider is available mostly for compatibility, you generally should use Proxy instead.
Currently only supports EPSG:4326 and EPSG:3857
Name should be "url template"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
template |
A URL pointing to the tile server. Should contain placeholders |
string |
Yes |
None |
width |
What to use for $width placeholder |
uint |
No |
256 |
height |
What to use for $height placeholder |
uint |
No |
256 |
srid |
What projection the bounds should be in and what to use for $srs placeholder. Can only be 4326 or 3857 |
uint |
No |
4326 |
Effect
Applies visual effects to an image generated by another provider. There’s a variety of options and many of them can have very poor performance, user beware.
This can only be used with layers that return JPEG or PNG images. The result always outputs in PNG format.
Name should be "effect"
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
provider |
The provider to get the imagery to apply the effect to |
Provider |
Yes |
None |
mode |
The effect to apply. Examples of the modes. Possible values: "blur", "gaussian", "brightness", "contrast", "gamma", "hue", "saturation", "dilate", "edge detection", "erode", "median", "threshold", "emboss", "grayscale", "invert", "sepia", "sharpen", or "sobel" |
String |
No |
normal |
intensity |
The intensity of the effect, exact meaning/value range depends on mode. Only applicable if mode is one of: "blur", "gaussian", "brightness", "contrast", "gamma", "hue", "saturation", "dilate", "edge detection", "erode", "median", or "threshold" |
Float |
No |
0 |
Example:
provider: name: effect mode: grayscale provider: name: proxy url: https://tile.openstreetmap.org/{z}/{x}/{y}.png
Blend
Allows you to combine the imagery from multiple providers. The simplest use case for this is to "sandwich" or "composite" semi-transparent images on top of each other. For example you can put county boundaries on top of a flood map or include a watermark on your maps. Multiple blending modes are available to fine-tune the effect.
This can only be used with layers that return JPEG or PNG images. Tiles will be scaled down to the lowest resolution to be combined and the combined result always output in PNG format.
Each downstream provider is called in parallel.
The following diagram depicts a possible request flow when using the Blend provider with the layers
parameter. Note that each downstream layer is individually cached; this is useful when it’s expected for requests to also come in for each of the individual layers but an unnecessary cost if not. If you only expect requests for the blended layer, either use the providers
parameter option or simply disable caching in the downstream layer(s).
Name should be "blend"
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
providers |
The providers to blend together. Order matters |
Provider[] |
Yes |
None |
mode |
How to blend the images. Examples of the modes. Possible values: "add", "color burn", "color dodge", "darken", "difference", "divide", "exclusion", "lighten", "linear burn", "linear light", "multiply", "normal", "opacity", "overlay", "screen", "soft light", "subtract" |
String |
No |
normal |
opacity |
Only applicable if mode is "opacity". A value between 0 and 1 controlling the amount of opacity |
Float |
No |
0 |
layer |
An alternative to the |
Object - See next rows |
No |
None |
layer.pattern |
A string with one or more placeholders present wrapped in curly brackets that match the layer placeholder you want to refer towards |
String |
Yes |
None |
layer.values |
An entry per instantiation of the layer, each entry should have a value for each placeholder in the pattern with the key being the placeholder and the value being the replacement value |
{"k":"v"}[] |
Yes |
None |
Example:
provider: name: blend mode: normal layer: pattern: noaa_poststorm_{date}{version} values: - date: 20230902 version: a - date: 20230901 version: b - date: 20230901 version: a - date: 20230831 version: b - date: 20230831 version: a
Fallback
Delegates calls to a Primary provider, then falls back Secondary provider when an error is returned or the tile is outside the valid zoom or bounds. This is useful, for example, where you’re integrating with a system that returns an error for requests outside of the coverage area and you want to return a Static image in those cases without it being logged as an error. It especially can be useful in conjunction with the Blend provider.
Currently the preAuth method is never called for the secondary provider, therefore only authless providers should be used as fallbacks. In the future we may include calls to the preAuth method but only when the fallback logic is triggered.
Currently the bounds parameter is only applied at a per-tile level. That is, the edge where the fallback begins to kick in will visibly change as you zoom in/out. In the future we may add an additional configuration option to make it apply at a per-pixel level instead.
Name should be "fallback"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
primary |
The provider to delegate to first |
Provider |
Yes |
None |
secondary |
The provider to delegate to if primary returns an error |
Provider |
Yes |
None |
zoom |
Zooming below or above this range will activate the fallback. Can be a single number, a range with a dash between start and end, or a comma separated list of the first two options. For example "4" "2-3" or "2,3-4" |
String |
No |
0-21 |
bounds |
Any tiles that don’t intersect with this bounds will activate the fallback |
Object with north, south, east, west |
No |
Whole world |
cache |
When to save the resulting tile to the cache. Options: always, unless-error, unless-fallback. |
string |
No |
unless-error |
Example:
provider: name: fallback cache: always zoom: 4-21 bounds: south: 51 north: 63 west: -7 east: 0.1 primary: name: proxy url: https://tile.openstreetmap.org/{z}/{x}/{y}.png secondary: name: static color: "0000"
Static
Generates the same exact image for every single tile. This is most useful when used with either the Fallback or Blend providers.
Name should be "static"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
image |
Either a filepath to an image on the local filesystem or one of the built-in images |
string |
Yes |
None |
color |
A hexcode (RGB or RGBA) of a color to return. Equivalent to specifying |
string |
No |
None |
Ref
Ref refers requests to another layer. This is pointless by itself but can be useful when combined with other providers to avoid repeating yourself.
For instance you can have a layer with a complex client configuration that utilizes a pattern
and points to a WMS server with the WMS layer being specified by a placeholder, then several other layers using Ref
that fill in the blank.
Name should be "ref"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
layer |
The layername to refer towards, treated the same if it were supplied in an incoming request. |
string |
Yes |
None |
Example
provider: name: ref layer: something_else
Custom
Custom providers implement your own custom logic for providing imagery from whatever source you can imagine. They require a custom Go script file interpreted using Yaegi. The main README has more detailed information on implementing custom providers and examples are available.
Name should be "custom"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
file |
An absolute file path to find the Go code implementing the provider |
string |
Yes |
None |
Any |
Any additional parameter you include will be automatically supplied to your custom provider as-is |
Any |
No |
None |
Transform
This provider allows you to implement a function to change the RGBA value of each individual pixel in imagery from another provider. Like the "Custom" provider this is implemented using Yaegi and requires you to include your own Go code. The interface for this is however much simpler, it requires just a single function:
func transform(r, g, b, a uint8) (uint8, uint8, uint8, uint8)
You can include the logic in a dedicated file, or inline in configuration. No special types or functions are available for use besides the standard library. A package declaration and any imports are optional.
This can only be used with layers that return JPEG or PNG images. Tiles will be scaled down to the lowest resolution to be combined and the combined result always output in PNG format.
Name should be "transform"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
file |
An absolute file path to find the Go code implementing the transformation |
string |
No |
None |
formula |
The go code implementing the transformation. Required if file isn’t included |
string |
No |
None |
provider |
The provider to get the imagery to transform |
Provider |
Yes |
None |
threads |
How many threads (goroutines) to use per tile. The typical tile has 65,536 pixels, setting this to 8 for instance means each thread has to process 8,192 pixels in parallel. This helps avoid latency becoming problematically slow. |
int |
No |
1 |
Example:
provider: name: transform threads: 8 formula: | func transform(r, g, b, a uint8) (uint8, uint8, uint8, uint8) { return g,b,r,a } provider: name: proxy url: https://tile.openstreetmap.org/{z}/{x}/{y}.png
CGI
The CGI provider allows a call-out to an external executable on the local system that’s responsible for generating the tile. This allows tilegroxy to act as the HTTP server for a CGI program like Apache httpd or nginx traditionally acts. The flagship use-case for this is to integrate with MapServer. A full example is available in examples/mapserver.
Name should be "cgi"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
Exec |
The path to the CGI executable |
string |
Yes |
None |
Args |
Arguments to pass into the executable in standard "split on spaces" format |
[]string |
No |
None |
Uri |
The URI (path + query) to pass into the CGI for the fake request - think mod_rewrite style invocation of the CGI |
string |
Yes |
None |
Domain |
The host to pass into the CGI for the fake request |
string |
No |
localhost |
Headers |
Extra headers to pass into the CGI with the request |
map[string][]string |
No |
None |
Env |
Extra environment variables to supply to the CGI invocations. If the value is an empty string it passes along the value from the main tilegroxy invocation |
map[string]string |
No |
None |
WorkingDir |
Working directory for the CGI invocation |
string |
No |
Base dir of exec |
InvalidAsError |
If true, if the CGI response includes a content type that isn’t in the Client's list of acceptable content types then it treats the response body as an error message |
bool |
No |
false |
Cache
The cache configuration defines the datastores where tiles should be stored/retrieved. We recommended you use a multi
-tiered cache with a smaller, faster "near" cache first followed by a larger, slower "far" cache.
There is no universal mechanism for expiring cache entries. Some cache options include built-in mechanisms for applying an TTL and maximum size however some require an external cleanup mechanism if desired. Be mindful of this as some options may incur their own costs if allowed to grow unchecked.
When specifying a cache ensure you include the name
parameter.
Multi
Implements a multi-tiered cache.
When looking up cache entries each cache is tried in order. When storing cache entries each cache is called simultaneously. This means that the fastest cache(s) should be first and slower cache(s) last. As each cache needs to be tried before tile generation starts, it is not recommended to have more than 2 or 3 caches configured.
Name should be "multi"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
tiers |
An array of Cache configurations. Multi should not be nested inside a Multi |
Cache[] |
Yes |
None |
Example:
cache:
name: multi
tiers:
- name: memory
maxsize: 1000
ttl: 1000
- name: disk
path: "./disk_tile_cache"
Disks
Stores the cache entries as files in a location on the filesystem.
If the filesystem is purely local then you will experience inconsistent performance if using tilegroxy in a high-availability deployment.
Files are stored in a flat structure inside the specified directory. No cleanup process is included inside of tilegroxy
itself. It is recommended you use an external cleanup process to avoid running out of disk space.
Name should be "disk"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
path |
The absolute path to the directory to store cache entries within. Directory (and tree) will be created if it does not already exist |
string |
Yes |
None |
filemode |
A Go filemode as an integer to use for all created files/directories. This might change in the future to support a more conventional unix permission notation |
uint32 |
No |
0777 |
Example:
"cache": {
"name": "disk",
"path": "./disk_tile_cache"
}
Memcache
Cache tiles using memcache.
Name should be "memcache"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
host |
The host of the memcache server. A convenience equivalent to supplying |
String |
No |
127.0.0.1 |
port |
The port of the memcache server. A convenience equivalent to supplying |
int |
No |
6379 |
keyprefix |
A prefix to use for keys stored in cache. Helps avoid collisions when multiple applications use the same memcache |
string |
No |
None |
ttl |
How long cache entries should persist for in seconds. Cannot be disabled. |
uint32 |
No |
1 day |
servers |
The list of servers to connect to supplied as an array of objects, each with a host and key parameter. This should only have a single entry when operating in standalone mode. If this is unspecified it uses the standalone |
Array of |
No |
host and port |
Example:
cache:
name: memcache
host: 127.0.0.1
port: 11211
Memory
A local in-memory cache. This stores the tiles in the memory of the tilegroxy daemon itself.
This is not recommended for production use. It is meant for development and testing use-cases only. Setting this cache too high can cause stability issues for the service and this cache is not distributed so can cause inconsistent performance when deploying in a high-availability production environment.
Name should be "memory"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
maxsize |
Maximum number of tiles to hold in the cache. Must be at least 10. Setting this too high can cause out-of-memory panics. This is not a guaranteed setting, which entry is evicted when exceeding this size is an implementation detail and the size can temporarily grow somewhat larger. |
uint16 |
No |
100 |
ttl |
Maximum time to live for cache entries in seconds |
uint32 |
No |
3600 |
Example:
cache:
name: memory
maxsize: 1000
ttl: 1000
Redis
Cache tiles using redis or another redis-compatible key-value store.
Name should be "redis"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
host |
The host of the redis server. A convenience equivalent to supplying |
String |
No |
127.0.0.1 |
port |
The port of the redis server. A convenience equivalent to supplying |
int |
No |
6379 |
db |
Database number, defaults to 0. Unused in cluster mode |
int |
No |
0 |
keyprefix |
A prefix to use for keys stored in cache. Serves a similar purpose as |
string |
No |
None |
username |
Username to use to authenticate with redis |
string |
No |
None |
password |
Password to use to authenticate with redis |
string |
No |
None |
mode |
Controls operating mode of redis. Can be |
string |
No |
standalone |
ttl |
How long cache entries should persist for in seconds. Cannot be disabled. |
uint32 |
No |
1 day |
servers |
The list of servers to connect to supplied as an array of objects, each with a host and key parameter. This should only have a single entry when operating in standalone mode. If this is unspecified it uses the standalone |
Array of |
No |
host and port |
Example:
{
"name": "redis"
"mode": "ring",
"servers": [
{
"host": "127.0.0.1",
"port": 6379
},
{
"host": "127.0.0.1",
"port": 6380
}
],
"ttl": 3600
}
S3
Cache tiles as objects in an AWS S3 bucket.
Ensure the user you’re using has proper permissions for reading and writing objects in the bucket. The permissions required are the minimal set you’d expect: GetObject and PutObject. It’s highly recommended to also grant ListBucket permissions, otherwise the log will contain misleading 403 error messages for every cache miss. Also ensure the user has access to the KMS key if using bucket encryption.
If you’re using a Directory Bucket AKA Express One Zone there’s a few things to configure:
-
Ensure
storageclass
is set to "EXPRESS_ONEZONE" -
The bucket contains the full name including suffix. For example:
my-tilegroxy-cache--use1-az6--x-s3
Name should be "s3"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
bucket |
The name of the bucket to use |
string |
Yes |
None |
path |
The path prefix to use for storing tiles |
string |
No |
/ |
region |
The AWS region containing the bucket. Required if region is not specified via other means. Consult AWS documentation for possible values |
string |
No |
None |
access |
The AWS Access Key ID to authenticate with. This is not recommended; it is offered as a fallback authentication method only. Consult AWS documentation for better options |
string |
No |
None |
secret |
The AWS Secret Key to authenticate with. This is not recommended; it is offered as a fallback authentication method only. Consult AWS documentation for better options |
string |
No |
None |
profile |
The profile to use to authenticate against the AWS API. Consult AWS documentation for specifics |
string |
No |
None |
storageclass |
The storage class to use for the object. You probably can leave this blank and use the bucket default. Consult AWS documentation for an overview of options. The following are currently valid: STANDARD REDUCED_REDUNDANCY STANDARD_IA ONEZONE_IA INTELLIGENT_TIERING GLACIER DEEP_ARCHIVE OUTPOSTS GLACIER_IR SNOW EXPRESS_ONEZONE |
string |
No |
STANDARD |
endpoint |
Override the S3 API Endpoint we talk to. Useful if you’re using S3 outside AWS or using a directory bucket |
string |
No |
AWS Auto |
Example:
cache:
name: s3
bucket: my-cache--use1-az6--x-s3
endpoint: "https://s3express-use1-az6.us-east-1.amazonaws.com"
storageclass: EXPRESS_ONEZONE
region: us-east-1
profile: tilegroxy_s3_user
Authentication
Implements incoming auth schemes. This is primarily meant for authentication but does include some authorization by limiting access to specific layers via JWT or custom schemes.
Requests that do not comply with authentication requirements will receive a 401 Unauthorized HTTP status code.
When supplying authentication ensure you include the name
parameter.
None
No incoming authentication, all requests are allowed. Ensure you have an external authentication solution before exposing this to the internet.
Name should be "none"
Static Key
Requires incoming requests have a specific key supplied as a "Bearer" token in a "Authorization" Header.
It is recommended you employ caution with this option. It should be regarded as a protection against casual web scrapers but not true security. It is recommended only for development and internal ("intranet") use-cases. Does not include any authz logic.
Name should be "static key"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
key |
The bearer token to require be supplied. If not specified |
string |
No |
Auto |
JWT
Requires incoming requests include a JSON Web Token (JWT). The signature of the token is verified against a fixed secret and grants are validated.
Currently this implementation only supports a single key specified against a single signing algorithm. The key can either be stored in configuration or supplied via environment variable. Support for multiple keys and keys pulled from secret stores is a desired future roadmap item.
The following claims are supported/enforced:
Claim | Implementation |
---|---|
exp |
Ensure the JWT hasn’t expired and it’s no further than a certain amount of time from now |
aud |
Validate it matches a specific value |
sub |
Validate it matches a specific value |
iss |
Validate it matches a specific value |
scope |
Validate it contains a specific scope OR ensure a given prefix plus the layer in the current request is contained in scope |
geohash |
Validate the current tile being requested is fully contained in the geohash |
Name should be "jwt"
Configuration options:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
Key |
The key for verifying the signature. The public key if using asymmetric signing. If the value starts with "env." the remainder is interpreted as the name of the Environment Variable to use to retrieve the verification key. |
string |
Yes |
None |
Algorithm |
Algorithm to allow for JWT signature. One of: "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "EdDSA" |
string |
Yes |
None |
HeaderName |
The header to extract the JWT from. If this is "Authorization" it removes "Bearer " from the start. Make sure this is in "canonical case" e.g. X-Header - auth will always fail otherwise |
string |
No |
Authorization |
MaxExpiration |
How many seconds from now can the expiration be. JWTs more than X seconds from now will result in a 401 |
uint32 |
No |
1 day |
ExpectedAudience |
Require the "aud" grant to be this string |
string |
No |
None |
ExpectedSubject |
Require the "sub" grant to be this string |
string |
No |
None |
ExpectedIssuer |
Require the "iss" grant to be this string |
string |
No |
None |
ExpectedScope |
Require the "scope" grant to contain this string |
string |
No |
None |
LayerScope |
If true the "scope" grant is used to whitelist access to layers |
bool |
No |
false |
ScopePrefix |
If true this prefix indicates scopes to use. For example a prefix of "tile/" will mean a scope of "tile/test" grants access to "test". Doesn’t impact ExpectedScope |
string |
No |
Empty string |
UserId |
Use the specified grant as the user identifier. This is just used for logging by default but it’s made available to custom providers |
string |
No |
sub |
Example:
authentication: name: jwt key: env.JWT_KEY algorithm: HS256
Custom
Allows you to specify your own logic controlling how auth tokens should be extracted and validated. This, like the custom provider, utilizes Yaegi to allow you to supply your own custom code.
To help mitigate the performance impact of calling the interpreted validate
method, a cache is utilized by default. In turn, to avoid concurrent requests that utilize the same token from causing repetitive calls to validate
, a pool of locks are utilized when the cache is enabled. The size of the lock pool is equal to the number of CPUs.
For more details on implementing the code for a custom authentication, see Extensibility
Name should be "custom"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
token |
How to extract the auth token from the request. Each Key/Value should be one of the options in the table above |
map[string]string |
Yes |
None |
cachesize |
Configures the size of the cache of already verified tokens used to avoid re-verifying every request. Set to -1 to disable |
int |
No |
100 |
file |
Contains the path to the file containing the go code to perform validation of the auth token as a file |
string |
No |
None |
Example:
authentication: name: custom file: examples/auth/custom_from_file.go token: header: X-Token
Secret
Configuring a Secret source allows you to pull keys, passwords, or any other sensitive value from an external secret store rather than placing them in your configuration directly. This is similar to the way you can reference environmental variables. Secrets loaded in this way are never written to disk. Properly externalizing secrets allows you to place your configuration into source control without modification.
Once a Secret source is configured, you can utilize it by including a configuration value like secret.key-name
. The secret source will then be queried for a secret named key-name
. If the secret store has no secret by that name, it will prevent the application from starting up. This effect applies to any other "entity" (cache, authentication, provider), for obvious reasons you can’t use a secret in the configuration for your secret source.
AWS Secrets Manager
This secret source utilizes the AWS Secrets Manager service.
This source includes a cache for values. This avoids repeatedly querying for the same value e.g. if it’s used by multiple providers. Currently secrets are only pulled at once at startup, however in the future this might be changed to re-pull periodically or upon configuration changes. Therefore it is advised to think through how often your secrets might rotate when configuring the TTL value, even though currently it only need to be a small value to span the initial start-up of the application.
Secrets Manager places secrets inside a JSON structure if configured through the console. To support that keys should be in the structure of id:key
with id
being the ID of the secret as a whole and key
being the key from the JSON Object stored in the secret. If the secret isn’t JSON then you only need to supply the id
by itself. You can override the separator used to be any value rather than a colon (:
).
This supports the standard means of authenticating with AWS. Ensure your user/role includes permission both to retrieve the secrets as well as permission to use the relevant KMS key to decrypt it.
Name should be "awssecretsmanager"
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
separator |
How to separate the Id of the secret from the JSON key in the secret name as a whole |
string |
No |
: |
ttl |
How long to cache secrets in seconds. Cache disabled if less than 0. |
int |
No |
1 hour |
region |
The AWS region containing the bucket. Required if region is not specified via other means. Consult AWS documentation for possible values |
string |
No |
None |
access |
The AWS Access Key ID to authenticate with. This is not recommended; it is offered as a fallback authentication method only. Consult AWS documentation for better options |
string |
No |
None |
secret |
The AWS Secret Key to authenticate with. This is not recommended; it is offered as a fallback authentication method only. Consult AWS documentation for better options |
string |
No |
None |
profile |
The profile to use to authenticate against the AWS API. Consult AWS documentation for specifics |
string |
No |
None |
Server
Configures how the HTTP server should operate
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
BindHost |
IP address to bind HTTP server to |
string |
No |
127.0.0.1 |
Port |
Port to bind HTTP server to |
int |
No |
8080 |
RootPath |
The root HTTP Path to serve all requests under. |
string |
No |
/ |
TilePath |
The HTTP Path to serve tiles under in addition to RootPath. The defaults will result in a path that looks like /tiles/{layer}/{z}/{x}/{y} |
string |
No |
tiles |
Headers |
Include these headers in all response from server |
map[string]string |
No |
None |
Production |
Hardens operation for usage in production. For instance, controls serving splash page, documentation, x-powered-by header. |
bool |
No |
false |
Timeout |
How long (in seconds) a request can be in flight before we cancel it and return an error |
uint |
No |
60 |
Gzip |
Whether to gzip compress HTTP responses |
bool |
No |
false |
Encrypt |
Configuration for enabling TLS (HTTPS). Don’t specify to operate without encryption (the default) |
No |
None |
|
Health |
Configuration to turn on endpoints for validating the health of the server on a secondary port |
No |
None |
The following can be supplied as environment variables:
Configuration Parameter | Environment Variable |
---|---|
BindHost |
SERVER_BINDHOST |
Port |
SERVER_PORT |
RootPath |
SERVER_ROOTPATH |
TilePath |
SERVER_TILEPATH |
Production |
SERVER_PRODUCTION |
Timeout |
SERVER_TIMEOUT |
Gzip |
SERVER_GZIP |
Client
Configures how the HTTP client should operate for tile requests that require calling an external HTTP(s) server.
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
UserAgent |
The user agent to include in outgoing http requests. |
string |
No |
tilegroxy/VERSION |
MaxLength |
The maximum Content-Length to allow incoming responses |
int |
No |
10 MiB |
UnknownLength |
Allow responses that are missing a Content-Length header, this could lead to excessive memory usage |
bool |
No |
false |
ContentTypes |
The content-types to allow remote servers to return. Anything else will be interpreted as an error |
string[] |
No |
image/png, image/jpg |
StatusCodes |
The status codes from the remote server to consider successful |
int[] |
No |
200 |
Headers |
Include these headers in requests |
map[string]string |
No |
None |
RewriteContentTypes |
Replaces |
map[string]string |
No |
{"application/octet-stream": ""} |
The following can be supplied as environment variables:
Configuration Parameter | Environment Variable |
---|---|
UserAgent |
CLIENT_USERAGENT |
MaxLength |
CLIENT_MAXLENGTH |
UnknownLength |
CLIENT_UNKNOWNLENGTH |
ContentTypes |
CLIENT_CONTENTTYPES |
StatusCodes |
CLIENT_STATUSCODES |
Log
Configures how the application should log during operation.
The Logging
section supports two keys: main
and access
which are objects described respectively below.
Example:
logging: access: console: false path: access.log main: level: debug format: json
Main Logs
Configures application log messages.
These log messages output in a structured log format, either with Key=Value attributes in plain (text) mode or as JSON. In either mode attributes are available driven by the HTTP request that is being processed. We try to avoid plain mode logs being overly verbose for readability, which means if you want all the attributes you’ll need to explicitly enable them. In JSON mode we assume you’re ingesting them into a system that handles formatting so include more attributes by default.
In order to avoid logging secrets you need to specify the headers to log. If you’re including auth information via the URL (not recommended) you should make sure Request is false to avoid logging those.
Level controls the verbosity of logs. There is no guarantee as to the specific log messages that will be outputted so you might see more or fewer log messages between versions of the application, especially at higher verbosity levels. Here are the general rules of what to expect for each level (from least to most verbose):
-
error: Only messages for things that are definitely a problem with your setup or the application itself. It’s recommended to configure alerts/notifications for error logs and if the issue is not User Error, please open a ticket for it: https://github.com/Michad/tilegroxy/issues
-
warn: Includes messages for things that might be an issue but isn’t critical to the core functioning of the system. For example an issue talking to your configured cache will come through as a warning.
-
info: Includes messages that allow you to see what’s happening in real time but without being overwhelmed with minutiae. Expect one or two log messages per request, including messages indicating requests with something unusual.
-
debug: Includes messages to help understand what’s happening for a given request execution. Expect a few log messages per request. This is more than you probably want in prod but can be useful when first integrating with the system.
-
trace: Includes messages for every level of the application as a request flows between layers. Expect several log messages per request, more for complex setups/layers. Very noisy but shouldn’t be a huge performance impact.
-
absurd: Includes more information than you will probably ever need. In some cases this can produce thousands of messages per request and will have a substantial performance cost.
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
Console |
Whether to write application logs to standard out |
bool |
No |
true |
Path |
The file location to write logs to. Log rotation is not built-in, use an external tool to avoid excessive growth |
string |
No |
None |
Format |
The format to output application logs in. Applies to both standard out and file out. Possible values: plain, json |
string |
No |
plain |
Level |
The most-detailed log level that should be included. Possible values: debug, info, warn, error, trace, absurd |
string |
No |
info |
Request |
Whether to include any extra attributes based on request parameters (excluding explicitly requested). If auto (default) it defaults true if format is json, false otherwise |
bool |
No |
auto |
Headers |
Headers to include as attributes in structured log messages. Attribute key will be in all lowercase. |
string[] |
No |
None |
The following can be supplied as environment variables:
Configuration Parameter | Environment Variable |
---|---|
Console |
LOGGING_MAIN_CONSOLE |
Path |
LOGGING_MAIN_PATH |
Format |
LOGGING_MAIN_FORMAT |
Level |
LOGGING_MAIN_LEVEL |
Request |
LOGGING_MAIN_REQUEST |
Headers |
LOGGING_MAIN_HEADERS |
Access Logs
Configures logs for incoming HTTP requests. Primarily outputs in standard Apache Access Log formats.
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
Console |
Whether to write access logs to standard out |
bool |
No |
true |
Path |
The file location to write logs to. Log rotation is not built-in, use an external tool to avoid excessive growth |
string |
No |
None |
Format |
The format to output access logs in. Applies to both standard out and file out. Possible values: common, combined |
string |
No |
common |
The following can be supplied as environment variables:
Configuration Parameter | Environment Variable |
---|---|
Console |
LOGGING_ACCESS_CONSOLE |
Path |
LOGGING_ACCESS_PATH |
Format |
LOGGING_ACCESS_FORMAT |
Telemetry
Configures telemetry using OpenTelemetry (OTEL). This configuration is currently limited to turning telemetry on and off, you must use standard OTEL environment variables to point the HTTP exporter to your collector.
More details on Telemetry capabilities can be found in Telemetry.adoc.
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
Enabled |
Turns on/off telemetry |
bool |
No |
false |
The following can be supplied as environment variables:
Configuration Parameter | Environment Variable |
---|---|
Enabled |
TELEMETRY_ENABLED |
Error
Configures how errors are returned to users.
There are four primary operating modes:
None: Errors are logged but not returned to users. In fact, nothing is returned to the users besides a relevant HTTP status code.
Text: Errors are returned in plain text in the HTTP response body
Image: The error message itself isn’t returned but the user receives an image indicating the general category of error. The images can be customized.
Image with Header : The same images are returned but the error message itself is returned as a special header: x-error-message.
It is highly recommended you use the Image mode for production usage. Returning an Image provides the most user friendly experience as it provides feedback to the user in the map they’re looking at that something is wrong. More importantly, it avoids exposing the specific error message to the end user, which could contain information you don’t want exposed. "Image with error" is useful for development workflows, it gives the same user experience but allows you to easily get to the error messages.
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
Mode |
The error mode as described above. One of: text none image image+header |
string |
No |
image |
Messages |
Controls the error messages returned as described below |
ErrorMessages |
No |
Various |
Images |
Controls the images returned for errors as described below |
ErrorImages |
No |
Various |
AlwaysOk |
If set we always return 200 regardless of what happens |
bool |
No |
false |
The following can be supplied as environment variables:
Configuration Parameter | Environment Variable |
---|---|
Mode |
ERROR_MODE |
AlwaysOk |
ERROR_ALWAYSOK |
Error Images
When using the image or image+header modes you can configure the images you want to be returned to the user. Either use a built-in image or an image provided yourself on the local filesystem via relative or absolute file path.
Configuration options:
Parameter | Description | Type | Required | Default |
---|---|---|---|---|
OutOfBounds |
The image to display for requests outside the extent of the layer |
string |
No |
embedded:transparent.png |
Authentication |
The image to display for auth errors |
string |
No |
embedded:unauthorized.png |
Provider |
The image to display for errors returned by the layer’s provider |
string |
No |
embedded:error.png |
Other |
The image to display for all other errors |
string |
No |
embedded:error.png |
The following can be supplied as environment variables:
Configuration Parameter | Environment Variable |
---|---|
OutOfBounds |
ERROR_IMAGES_OUTOFBOUNDS |
Authentication |
ERROR_IMAGES_AUTHENTICATION |
Provider |
ERROR_IMAGES_PROVIDER |
Other |
ERROR_IMAGES_OTHER |
Image Options
In addition to an image on the filesystem you can refer to a static color or a built-in image.
There are currently 4 built-in images available:
Image name | Description | Preview |
---|---|---|
transparent.png |
A fully transparent image meant to be used for requests outside the valid range of a layer |
|
red.png |
A semi-transparent solid red image |
|
error.png |
A semi-transparent solid red image with the word "Error" in white |
|
unauthorized.png |
A semi-transparent solid red image with the words "Not Authorized" in white |
To utilize them prepend "embedded:" before the name. For example embedded:transparent.png
You can also reference any color by including an hex code prefixed by "color:". The color code can be RGB or RGBA and have single or double hex digits. For example the following all generate an identical violet tile: color:FF00FFFF
, color:FF00FF
, color:F0F
, color:F0FF
Error Messages
The templates used for error messages for the majority of errors can be configured. Since tilegroxy is a backend service the main time you see words coming from it is in error messages, so it’s all the more important to be flexible with those words. This is most useful for those whose primary language is not English and want to decrease how often they need to deal with translating. Unfortunately, many lower-level errors can return messages not covered by these string.
The following are currently supported:
NotAuthorized InvalidParam RangeError ServerError ProviderError ParamsBothOrNeither ParamsMutuallyExclusive EnumError