Secrets Viewtool

Last Updated: Aug 15, 2023
documentation for the dotCMS Content Management System

The $dotsecrets Viewtool allows passing of a secret string or character array — such as a token, key, password, etc. — via Velocity, without including sensitive data in the VTL file.

The Secrets Viewtool debuted in release 23.07. Its toolbox.xml mapping is as follows:

    <tool>
        <key>dotsecrets</key>
        <scope>application</scope>
        <class>com.dotcms.rendering.velocity.viewtools.SecretTool</class>
    </tool>

General Security Notes

The handling of secrets in any context calls for care; misuse of the Secrets Viewtool can lead to exposure of sensitive data.

We recommend using the Secrets Viewtool in conjunction with a custom Scripting API endpoint or the Velocity Script Workflow Sub-Action, as these offer no opportunity for a secret to be unintentionally rendered.

When used within a Widget or Page, avoid printing $dotsecrets anywhere it has the potential to be rendered. One easy guideline for this use case is to use the viewtool only within the parentheses of a Velocity directive. For example:

#if($userInput == $dotsecrets[$userKey])
    Render this block.
#end

This ensures the secret will not appear in a user's browser session.

When using the Secrets Viewtool as part of an API call to an external application, it is important that the data retrieved from $dotsecrets be sent directly to that external target instead of back to a browser session. While many in many contexts it is appropriate to offload API calls to a client to spare server load, this pattern is not recommended in the context of $dotsecrets, as it virtually guarantees the secret's exposure. Instead, wrap the call in a Scripting API method; if the server handles the sensitive call and simply returns its results to the client, this presents no such risk.

Usage

App Configuration

The Secrets Viewtool interfaces with a special app called Dot Velocity Secrets, which lives under System → Apps. All keys must be stored as Custom Properties under either a specific site or the system host. No site can access the secrets of another site, though secrets stored at the system host level are accessible from any site. As a general rule, it is better to make secrets as narrowly accessible as possible; accordingly, it is best to use system host secrets only in cases where one operation affects multiple sites.

The Dot Velocity Secrets App, seen with example values such as key "test1" and value "secret1".

Headless Configuration

The Dot Velocity Secrets App can be configured headlessly through a special /v1/apps/dotVelocitySecretApp REST API endpoint. To POST to this endpoint, use the relevant site identifier as a path parameter, and include a JSON payload of properties with the following schema:

{
    "property": {
        "hidden": true|false,
        "value": "string"
    }
}

There is a single reserved property called title, which provides a descriptive title for the Site entry within the app. Its hidden property cannot be changed from false.

All other properties are keys corresponding to a secret value.

Example of updating the dotCMS Demo Site:

curl -v -u admin@dotcms.com:admin -X POST https://demo.dotcms.com/api/v1/apps/dotVelocitySecretApp/48190c8c-42c4-46af-8d1a-0cd5db894797 -H "Content-Type: application/json" -d '{
    "title":{"hidden":false,"value":"dotCMS demo site secrets"},
    "test2":{"hidden":true,"value":"secret2"},
    "test1":{"hidden":false,"value":"secret1"}
    }'

Similarly, updating the System Host:

curl -v -u admin@dotcms.com:admin -X POST https://demo.dotcms.com/api/v1/apps/dotVelocitySecretApp/SYSTEM_HOST -H "Content-Type: application/json" -d '{
    "title":{"hidden":false,"value":"dotCMS demo site system secrets"},
    "sysSecret1":{"hidden":false,"value":"thebigsecret"}
    }'

Using either of those URLs with the GET HTTP method will simply return their properties. If you GET the endpoint without a path parameter, it returns a list of site entries within the app, but not their individual properties.

Velocity Commands

CommandResult
$dotsecrets.get("foo") or $dotsecrets.foo or $dotsecrets["foo"] or $dotsecrets[$foo]Four equivalent ways to retrieve the local site secret stored with key foo — in the last case after the declaration of #set($foo = "foo")
$dotsecrets.getSystemSecret("foo")Retrieves the system host secret stored with the key foo.
$dotsecrets.getCharArray("foo")Similar to .get("foo"), but returns the local site secret as an array of characters instead of a string.
$dotsecrets.getCharArraySystemSecret("foo")Similar to .getSystemSecret("foo"), but returns the system host secret as an array of characters instead of a string.

Examples

Passing an API Key or Token in Velocity

After storing the access token in the Dot Velocity Secret App under the key myKey, you can include it in the Authorization header of an API call as follows:

#set($queryString = "{ \"query\":\"hello world\" }")
#set($timeout = 3000)
#set($headers = {})
$!{headers.put("Authorization", "bearer ${dotsecrets.myKey}")}
$!{headers.put("Content-type" , "application/json")}
#set($results = $json.post("https://api.example.com/endpoint", $timeout, $headers, $queryString))

On this page

×

We Dig Feedback

Selected excerpt:

×