Rug Functions

Rug Functions, as indicated by their name, are functions that can be invoked from within Event or Command Handlers. They can be scheduled for invocation by adding an instruction of kind execute to a plan:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
plan.add(
    {
        instruction: {
            kind: "execute",
            name: "http",
            parameters: {
                url: "https://api.github.com/repos/atomist/rug",
                method: "post",
                config: {
                    headers: {
                        "Content-Type": "application/json",
                        "Authorization": `token #{github://user_token?scopes=repo}`,
                    },
                    body: JSON.stringify(createRepoRequest)
                }
            }
        },
        onSuccess: new DirectMessage("Woot!", new ChannelAddress("#random")),
        onError: new DirectMessage("Un oh", new ChannelAddress("#random"))
    }
)

The plan above instructs the Rug Runtime to invoke the http Rug Function, passing all the parameters to it, and sending appropriate messages to the #random channel onSuccess or onError.

To use a Rug Function from an Event or Command Handler, its archive’s coordinates must be present in the .atomist.extensions section of the Rug project’s package.json.

Security

All Rug Function archives must be signed by Atomist and be explicitly whitelisted in the Atomist service. Otherwise, the execution of the invoking handler will be aborted.

Secrets can also be passed to Rug Functions, but currently this is only supported for Command Handlers.

The special #{<secret path>} notation used above is a way of injecting the value of a secret (in this case, a GitHub token with repo scope) in to the parameters to a function via string filtering. Rug Functions can also be annotated so that if the secrets required are known in advance, we don’t need to use paramter filtering.

The following Rug Function archives available:

Creating your own Rug functions

Right now there is no support for user-created Rug functions. Please get in touch by joining our Slack team if you need one that doesn’t already exist.

Secrets

Secrets are pieces of sensitive information stored securely by Atomist. Secrets are used by Rug Functions to provide access to secured systems, such as the GitHub API.

Handlers that invoke Rug Functions that require secrets must use the @Secrets decorator to declare to the Rug runtime that those secrets will be required during the execution of the handler’s CommandPlan:

...
@Secrets("github://user_token?scopes=repo,read:org")
class CloseIssueCommand implements HandleCommand {
    //...
}

The @Secrets decorator takes a comma separate list of secret paths. The decorator provides enough context to the Atomist Bot such that it can initiate the secure collection of the require secret data, such as a GitHub token collected via OAuth flow.

Confidentiality

All sensitive data stored by Atomist are encrypted at rest in Vault.

There are currently two types of secrets:

  • GitHub tokens: automatically collected by the Atomist Bot
    • "github://user_token?scopes=repo" - repo scoped user token
    • "github://team_token?scopes=repo" - repo scoped team token Both user and team GitHub tokens require the scopes needed by the token to be provided as a comma-separated list.
  • Generic Secrets: manual collection
    • "secret://user?path=/some/secret" - generic user secret
    • "secret://team?path=/some/secret" - generic team secret

Generic Secrets

These are currently only available for very specific and mostly internal use cases as we currently have no secure public mechanism for collecting and storing them, though this is something we are hoping to support in the near future. They are mentioned here to avoid any confusion when seen in publically visible Handlers.