Secure Map Services API
Last Updated: August 2026
Secure map services are map services (e.g.: OGC WMS endpoints) that require credentials to access. The Secure Map Services API allows a developer to register the endpoint and credentials of such a service once, and then allows apps to consume that service without ever storing or handling the credentials themselves.
In addition, requests can optionally be routed through a proxy endpoint provided by Tethys Portal so that credentials are never sent to the browser. See Proxying Requests for more details.
Tip
For a step-by-step tutorial on using secure map services in your app, see the Secure Map Services Tutorial.
Two authentication methods are supported:
API Key: a key is stored (encrypted) with the service and added to each request as a query parameter.
OAuth2: an OAuth2 access token is retrieved from the requesting user's linked social auth account and added to each request as a
Bearertoken.
Important
API keys assigned to a SecureMapService are encrypted before they are stored in the database. This requires a SALT_KEY to be set in your portal_config.yml. If you have not already done so, generate one as follows:
tethys gen portal_config
tethys settings --generate-salt-key
Secure Map Service Settings
Using secure map services in your app is accomplished by adding the secure_map_service_settings() method to your app class, which is located in your app configuration file (app.py). This method should return a list or tuple of SecureMapServiceSetting objects. For example:
from tethys_sdk.app_settings import SecureMapServiceSetting
class App(TethysAppBase):
"""
Tethys App Class for My First App.
"""
...
def secure_map_service_settings(self):
"""
Example secure_map_service_settings method.
"""
secure_map_service_settings = (
SecureMapServiceSetting(
name='primary_secure_map_service',
description='Secure map service for app to use.',
required=True,
),
)
return secure_map_service_settings
Caution
The ellipsis in the code block above indicates code that is not shown for brevity. DO NOT COPY VERBATIM.
Unlike other Tethys Service settings, a SecureMapServiceSetting does not specify an engine. The type of service and how it is authenticated are properties of the SecureMapService that is assigned to the setting, not of the setting itself.
Register a Secure Map Service
Before a SecureMapService can be assigned to a setting, it must be registered in the Admin Interface of Tethys Portal:
Access the Admin interface of Tethys Portal by clicking on the drop down menu next to your user name and selecting the "Site Admin" option.
Scroll down to the Tethys Services section of the Admin Interface and select the link titled Secure Map Services.
Click on the Add Secure Map Service button.
Fill in the connection information for the service (see the table below).
Press the Save button to save the new
SecureMapService.
The following fields are available on a SecureMapService:
Field |
Description |
|---|---|
Name |
Unique name used to identify the service. |
Endpoint |
The URL of the map service. |
Legend Title |
The title to use for the legend when the service is added to a map as a layer. |
Authentication Method |
One of API Key or OAuth2. The fields that apply to the other method are hidden in the admin form. |
API Key |
The API key to use when the authentication method is API Key. The value is encrypted before it is stored in the database. |
OAuth2 Provider |
The social auth backend to retrieve the access token from when the authentication method is OAuth2. The options are populated from the authentication backends that are enabled for the portal (see Single Sign On (Optional)). |
Service Type |
The type of service: WMS ( |
Use Proxy for Requests |
When checked, requests are routed through a Tethys Portal proxy endpoint so that credentials are never exposed to the browser. See Proxying Requests. |
Parameters |
A JSON object of additional query parameters to include with each request to the service. See Service Parameters. |
Tip
You do not need to create a new SecureMapService for each SecureMapServiceSetting or each app. Apps and SecureMapServiceSettings can share SecureMapServices.
Assign Secure Map Service
The SecureMapServiceSetting can be thought of as a socket for a connection to a SecureMapService. Before we can do anything with the SecureMapServiceSetting we need to "plug in" or assign a SecureMapService to the setting. Assigning a SecureMapService is done through the Admin Interface of Tethys Portal as follows:
Navigate to App Settings Page
Return to the Home page of the Admin Interface using the Home link in the breadcrumbs.
Scroll to the Tethys Apps section of the Admin Interface and select the Installed Apps link.
Select the link for your app from the list of installed apps.
Assign
SecureMapServiceto the appropriateSecureMapServiceSettingScroll to the Secure Map Service Settings section and locate the
SecureMapServiceSetting.
Note
If you don't see the
SecureMapServiceSettingin the list, uninstall the app and reinstall it again.Assign the appropriate
SecureMapServiceto yourSecureMapServiceSettingusing the drop down menu in the Secure Map Service column.Press the Save button at the bottom of the page to save your changes.
Note
During development you will assign the SecureMapService setting yourself. However, when the app is installed in production, this step is performed by the portal administrator upon installing your app, which may or may not be yourself.
Working with Secure Map Services
After a secure map service has been assigned to a setting, use the get_secure_map_service() method of the app class to retrieve it. The value that is returned depends on which of the as_ arguments is provided.
Get the Service
Called with only a name, get_secure_map_service() returns the SecureMapService object that is assigned to the setting:
from .app import App
service = App.get_secure_map_service('primary_secure_map_service')
Get an Endpoint
Pass as_endpoint=True to get the URL of the service with all of its parameters (and the API key, if applicable) applied:
from .app import App
endpoint = App.get_secure_map_service('primary_secure_map_service', as_endpoint=True)
Note
A lazy string is returned when as_endpoint is True. This ensures the endpoint reflects the current state of the service's settings every time it is used, and allows the endpoint to be referenced at import time (e.g.: as a MapLayout basemap) before the app URLs have been registered.
Get a Map Layer
Pass as_layer=True to get an MVLayer for the service that can be added to a MapView or MapLayout. The source of the layer is the Service Type of the service and the legend_title is the Legend Title of the service:
from .app import App
layer = App.get_secure_map_service('primary_secure_map_service', as_layer=True)
If the service uses OAuth2 authentication and is not proxied, the access token must be retrieved from the user making the request, so the request_user argument is required:
layer = App.get_secure_map_service(
'primary_secure_map_service',
as_layer=True,
request_user=request.user,
)
Specifying the Source Projection
GML layers and Vector layers that are loaded with a token are transformed from the coordinate reference system of the source data to the projection of the map when they are rendered. That CRS is determined in the following order:
The
data_projectionoption of the layer, if one is set.The CRS declared by the data itself (
srsNamein GML/WFS responses,crsin GeoJSON).EPSG:4326, which is assumed when the data declares no CRS.
Most services declare their CRS, so no additional configuration is needed. If a service returns data in a projection other than EPSG:4326 without declaring it, set the data_projection option on the layer that is returned:
layer = App.get_secure_map_service(
'primary_secure_map_service',
as_layer=True,
request_user=request.user,
)
layer.options['data_projection'] = 'EPSG:26912'
Note
param_overrides cannot be used to set data_projection, because those values are added to the query string of the request to the service. Set it on the options of the returned MVLayer as shown above.
Get a Response
Pass as_response=True to perform the request server-side and get the resulting requests.Response object. This is useful for services that return data to be processed by the app rather than rendered as a map layer:
from .app import App
response = App.get_secure_map_service(
'primary_secure_map_service',
as_response=True,
request_user=request.user,
)
data = response.json()
Note
As with as_layer, request_user is required when the service uses OAuth2 authentication. An exception is raised if the request is not successful.
Service Parameters
The Parameters field of a SecureMapService is a JSON object of query parameters that are added to every request made to the service. For example, the following parameters could be used for a WMS service:
{
"service": "WMS",
"request": "GetMap",
"layers": "my:layer",
"format": "image/png",
"transparent": true
}
String values may contain placeholders that reference fields of the SecureMapService, using Python's string.Template syntax. This is most commonly used to place the API key in a parameter with a name other than api_key:
{
"connectId": "${api_key}"
}
Note
If the API key is not referenced by any parameter, it is added automatically as a parameter named api_key.
Overriding Parameters Per Request
Pass a param_overrides dictionary to get_secure_map_service() to add to or replace the parameters of the service for a single request. This does not modify the SecureMapService:
from .app import App
response = App.get_secure_map_service(
'primary_secure_map_service',
as_response=True,
param_overrides={'layers': 'my:other_layer'},
request_user=request.user,
)
Updating Parameters Permanently
Use the update_secure_map_service_params() method of the app class to permanently update the parameters of the SecureMapService that is assigned to a setting. The given parameters are merged with the existing parameters and saved:
from .app import App
App.update_secure_map_service_params(
'primary_secure_map_service',
{'layers': 'my:other_layer'},
)
Caution
SecureMapServices can be shared by multiple settings and apps, so updating the parameters of a service affects every app that uses it.
Proxying Requests
When the Use Proxy for Requests option is enabled on a SecureMapService, the endpoint that is returned by get_secure_map_service() is not the endpoint of the map service, but rather a URL to a proxy view provided by Tethys Portal (secure-map-proxy/<id>/). The browser makes its requests against the proxy, which then adds the credentials and parameters of the service server-side and streams the response back. As a result, the API key or access token is never sent to the browser.
The proxy view requires the user to be logged in, and for OAuth2 services it uses the access token of the logged in user making the request.
Tip
Enable Use Proxy for Requests for any service whose credentials should not be visible to end users. Without it, the API key is included in the URL of the tile requests that the browser makes, where it can be read from the browser's developer tools.
Requiring an OAuth2 Provider
Services that use OAuth2 authentication require the user to have linked the corresponding social auth account to their Tethys Portal account. To require users to link an account before they can access an app, add the app package and provider name to the OAUTH2_REQUIREMENTS portal setting:
tethys settings --set OAUTH2_REQUIREMENTS.my_first_app my_provider
Users who access the app without having linked an account for the given provider are redirected to their user settings page with a message prompting them to link it.
Note
The provider must also be configured as an authentication backend for the portal. See Single Sign On (Optional) for more details.
API Documentation
- TethysAppBase.secure_map_service_settings()
Override this method to define secure map service connections for use in your app.
- Returns:
A list or tuple of
SecureMapServiceSettingobjects.- Return type:
iterable
Example:
from tethys_sdk.app_settings import SecureMapServiceSetting class MyFirstApp(TethysAppBase): def secure_map_service_settings(self): """ Example secure_map_service_settings method. """ secure_map_services = ( SecureMapServiceSetting( name='primary_secure_map_service', description='Secure Map Service for app to use', required=True, ), ) return secure_map_services
- classmethod TethysAppBase.get_secure_map_service(name, as_endpoint=False, as_layer=False, as_response=False, as_token=False, param_overrides=None, request_user=None, source_options=None, layer_options=None)
Retrieves secure map service assigned to named SecureMapServiceSetting for the app.
- Parameters:
name (str) -- name of the SecureMapServiceSetting as defined in the app.py.
as_endpoint (bool) -- Returns endpoint url string if True, Defaults to False.
as_layer (bool) -- Returns an MVLayer object if True, Defaults to False.
as_response (bool) -- Returns requests.Response object if True, Defaults to False.
as_token (bool) -- Returns an OAuth2 token string if True, Defaults to False.
param_overrides (dict) -- Dictionary of parameters to override for the map service request. Defaults to None.
request_user (User) -- Django User object to use for the request. Defaults to None.
source_options (dict) -- Used with as_layer. Merged into the
optionsof the returned MVLayer (OpenLayers ol.source options, e.g.data_projection).urlandtokenare set by the service and cannot be overridden. Defaults to None.layer_options (dict) -- Used with as_layer. Merged over
{"visible": True}into thelayer_optionsof the returned MVLayer (OpenLayers ol.layer options, e.g.style). Defaults to None.
- Returns:
SecureMapService assigned to setting.
- Return type:
SecureMapService
NOTE: When
as_endpointis True a lazy string is returned. This ensures the endpoint reflects the current state of the map service's settings every time it is used.
- classmethod TethysAppBase.update_secure_map_service_params(name, params)
Update the params for a given SecureMapServiceSetting's assigned SecureMapService.
NOTE: This method will not update the params for the SecureMapServiceSetting itself. It will only update the params for the assigned SecureMapService.
- Parameters:
name (str) -- name of the SecureMapServiceSetting as defined in the app.py.
params (dict) -- dictionary of params to update for the service.