NAV
Switch version:

Authorization Plugins

Extension Information

Availability GoCD version 19.2.0 onwards
Extension Name authorization
Extension API Version 2.0

Introduction

The Authorization endpoints are GoCD extensions to build plugins which provide authentication and authorization.

GoCD enforces authorization by restricting certain operations to specific users and groups of users (“roles”).

Without the use of authorization plugins, roles can only be managed through GoCD and it does not provide an ability to use roles defined in systems used for authentication (for example in LDAP groups). With this limitation, administrators need to configure roles in multiples places.

Authorization plugin endpoint allows GoCD to delegate both authentication and authorization of users to plugins. The plugins will have the flexibility to use any authorization service providers like LDAP, Google, GitHub etc.

If you’re looking to start away with a basic template for authorization plugins, we recommend forking this Github repository.

Configuring Authorization Plugins

Authorization Plugins need two types of configuration, <authConfig/> and <pluginRole/>.

Authorization Configuration

An example authorization configuration

  <security>
    <authConfigs>
      <authConfig id="profile-id" pluginId="cd.go.authentication.ldap">
        <property>
          <key>Url</key>
          <value>ldap://ldap-server-url</value>
        </property>
        <property>
          <key>ManagerDN</key>
          <value>cn=go,ou=Teams,dc=corporate,dc=example,dc=com</value>
        </property>
        <property>
          <key>Password</key>
          <value>secret</value>
        </property>
        <property>
          <key>SearchBases</key>
          <value>ou=Teams,dc=corporate,dc=example,dc=com</value>
        </property>
        <property>
          <key>UserLoginFilter</key>
          <value>(sAMAccountName={0})</value>
        </property>
        <property>
          <key>UserSearchFilter</key>
          <value>(|(sAMAccountName=*{0}*)(uid=*{0}*)(cn=*{0}*)(mail=*{0}*)(otherMailbox=*{0}*))</value>
        </property>
        <property>
          <key>DisplayNameAttribute</key>
          <value>displayName</value>
        </property>
        <property>
          <key>EmailAttribute</key>
          <value>mail</value>
        </property>
      </authConfig>
    </authConfigs>
  </security>

Authorization configuration will usually allow administrators to configure the connection settings for your authorization plugin, and may include configuration like URLs and credentials, among others.

GoCD administrators could provide multiple authorization configurations to connect with multiple authorization servers.

Plugin Role Configuration

An example plugin role configuration

<pluginRole name="spacetiger" authConfigId="ldap">
  <property>
    <key>MemberOfAttribute</key>
    <value>memberOf</value>
  </property>
  <property>
    <key>MatchingGroups</key>
    <value>CN=Dev,OU=Groups,DC=some,DC=enterprise,DC=com</value>
  </property>
</pluginRole>

This is used to define roles in GoCD, unlike the current roles which contains a list of users pluginRole provides configuration to map a GoCD role to a role defined in an external authorization service. e.g pluginRole can be used to define mappings between LDAP group and GoCD roles.

Requests from the GoCD server

Authorization extension exposes endpoints to support authentication and authorization.

All Authorization plugins should implement the following messages to support authentication.

If a plugin supports web based authentication, apart from the above, the plugin must implement the following messages. The plugin should use the supported_auth_type capability to expose this feature.

For a plugin to support authorization, the following messages must be implemented. The plugin should use the can_authorize capability to expose this feature.

If a plugin supports search, the following message must be implemented in order to serve search request from server. The plugin should use the can_search capability to expose this feature.

If a plugin supports get roles, the plugin must implement the following messages. The plugin should use the can_get_user_roles capability to expose this feature.

Get Plugin Icon

This call is expected to return the icon for the plugin, so as to make it easy for users to identify the plugin.

Request name

go.cd.authorization.get-icon

Request body

The server will not provide a request body.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

An example plugin response body:

{
  "content_type": "image/svg+xml",
  "data": "PHN2ZyB2ZXJzaW9u..."
}

The plugin is expected to return an image object.

Get Plugin Capabilities

This message is a request to the plugin to provide plugin capabilities. Based on these capabilities GoCD would enable or disable the plugin features for a user.

Request name

go.cd.authorization.get-capabilities

Request body

Server sends request with Empty request body.

Response Body

An example response body:

{
  "supported_auth_type": "password",
  "can_search": true,
  "can_authorize": true,
  "can_get_user_roles": true
}

The response body will contain the following JSON elements:

Key Type Description
supported_auth_type String This key determines plugin authentication method. It can be one of password or web.
can_search Boolean Whether Plugin supports search or not, depends on this boolean value.
can_authorize Boolean Whether Plugin supports authorization, depends on this boolean value.
can_get_user_roles Boolean Whether Plugin supports get roles or not, depends on this boolean value.

The plugin is expected to return status 200 if it can understand the request.

Get Authorization Configuration Metadata

This is a message that the plugin should implement, to allow users to configure authorization configuration (<authConfig>) from the Authorization Configuration View in GoCD.

Request name

go.cd.authorization.auth-config.get-metadata

Request body

The server will not provide a request body.

Response Body

An example response body:

[
  {
    "key": "Url",
    "metadata": {
      "required": true,
      "secure": false
    }
  },
  {
    "key": "ManagerDN",
    "metadata": {
      "required": true,
      "secure": false
    }
  }
]

The response body will contain the following JSON elements:

Key Type Description
key String The name of the configuration property supported by an authorization configuration.
metadata Object The metadata associated with the key used in the authorization configuration. Valid keys are required and secure.

The plugin is expected to return status 200 if it can understand the request.

Get Authorization Configuration View

This is a message that the plugin should implement, to allow users to configure authentication configuration (<authConfig>) from the Authorization Configuration View in GoCD.

Request name

go.cd.authorization.auth-config.get-view

Request body

The server will not provide a request body.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

An example response body:

{
  "template": "<div>some html</div>"
}

A JSON settings view object

Validate Authorization Configuration

This message must be implemented in order to validate the configuration. The plugin would receive this message from GoCD server during config save.

Request name

go.cd.authorization.auth-config.validate

Request body

An example validation request body for LDAP plugin

{
  "Url": "Any invalid Url",
  "SearchBase": "ou=users,ou=system",
  "ManagerDN": "uid=admin,ou=system",
  "SearchFilter": "uid",
  "Password": "secret",
  "DisplayNameAttribute": "displayName",
  "EmailAttribute": "mail"
}

The request body will contain a configuration from authorization configuration, for which validation would have been called.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

The plugin should respond with JSON array response for each configuration key that has a validation error

[
  {
   "key": "Url",
   "message": "Url is invalid."
  }
]

If any of the input keys have a validation error on them, the plugin is expected to return a list of validation error objects. If the configuration is valid, the plugin should return an empty JSON array.

Authenticate User

This message is a request to the plugin to authenticate and authorize a user, along with the user credentials the GoCD server sends all known <authConfig /> and <roleConfig /> configured for the plugin. In case of multiple <authConfig /> configured for the plugin, the plugin is expected to try authenticating the user against each config until a successful authentication.

GoCD forces a perodic re-authentication of users, this is to ensure any changes like removing of users or roles in the external authorization server are reflected in GoCD.

Request name

go.cd.authorization.authenticate-user

Request body

The plugin will receive the following JSON body for password based authorization —

{
  "credentials" : {
    "username": "jdoe",
    "password": "secret"
  },
  "auth_configs": [{
    "id": "internal_ldap",
    "configuration": {
      "url": "ldap://ldap1.example.com"
    }
  },
  {
    "id": "external_ldap",
    "configuration": {
      "url": "ldap://ldap2.example.com"
    }
  }],
  "role_configs": [{
    "name": "admin",
    "auth_config_id": "internal_ldap",
    "configuration": {
      "memberOf": "ou=some-value"
    }
  },
  {
    "name": "view",
    "auth_config_id": "external_ldap",
    "configuration": {
      "memberOf": "ou=some-value"
    }
  }]
}

Key Type Description
credentials Object For a password based plugins, the server sends the ‘username’ and ‘password’ provided by the user at the time of login. For web based plugins, the server sends the data received from Fetch Access Token call made to the plugin.
auth_configs Object This key contains list of <authconfig> configured for the plugin.
role_configs Object This key contains list of <roleconfig> configured for the plugin.

Response Body

An example response body:

{
  "user": {
    "username": "jdoe",
    "display_name": "John Doe",
    "email_id": "jdoe@example.com"
  },
  "roles": ["blackbird", "spacetiger"]
}

The response body will contain the following JSON elements:

Key Type Description
user Object This json object contains user details like username, display_name and email_id.
roles Array Array of roles associated with authenticated user.

The plugin is expected to return status 200 if it can understand the request.

Verify Connection

The plugin must implement this message in order to verify if a connection can be established with the authorization server using the authorization configuration.

The plugin is expected to validate the configuration before trying to check connection.

Request name

go.cd.authorization.auth-config.verify-connection

Request body

An example LDAP plugin authorization configuration request body to verify connection

{
  "Url": "ldap://foo.bar.com:389",
  "SearchBase": "ou=users,ou=system",
  "ManagerDN": "Dummy manager dn",
  "UserLoginFilter": "(uid={0})",
  "Password": "secret",
  "DisplayNameAttribute": "displayName",
  "EmailAttribute": "mail"
}

The request body will contain the authorization configuration for which verify connection is executed.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

Example response body based on successful verification

{
  "status": "success",
  "message": "Check connection passed"
}

Example response body based on verification failed

{
  "status": "failure",
  "message": "Check connection failed, unable to reach ldap://my_ldap_server"
}

Example response body based on validation failed

{
  "status": "validation-failed",
  "message": "Validation failed for the given authorization config",
  "errors": [
    {
      "key": "ManagerDN",
      "message": "Manager dn is invalid."
    }
  ]
}

The response body will contain the following JSON elements:

Key Type Description
status String Status of verify connection call, can be eithe of success or failure or validation-failure
message String Message corresponding to the verify connection status.
errors Object In case of validation errors plugin should return a list of validation error objects.

Get Role Configuration Metadata

This is a message that the plugin should implement to allow users to configure role configuration(<pluginRole>) from the Role Configuration View in GoCD. The role configuration should provide a way for admins to map Authorization Server roles with GoCD roles(e.g map LDAP groups to GoCD roles).

Request name

go.cd.authorization.role-config.get-metadata

Request body

The server will not provide a request body.

Response Body

An example response body:

[
  {
    "key": "MemberOf",
    "metadata": {
      "required": true,
      "secure": false
    }
  }
]

The response body will contain the following JSON elements:

Key Type Description
key String The name of the configuration property supported by an authorization configuration.
metadata Object The metadata associated with the key used in the authorization configuration. Valid keys are required and secure.

The plugin is expected to return status 200 if it can understand the request.

Get Role Configuration View

This is a message that the plugin should implement, to allow users to configure role configuration (<pluginRole>) from the Role Configurations View in GoCD.

Request name

go.cd.authorization.role-config.get-view

Request body

The server will not provide a request body.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

A JSON settings view object

An example response body:

{
  "template": "<div>some html</div>"
}

Validate Role Configuration

If a plugin requires any authorization configuration, this message must be implemented in order to validate the configuration.

Request name

go.cd.authorization.role-config.validate

Request body

An example validation request body for LDAP plugin

{
  "MemberOf": "ou=blackbird,ou=area51,dc=example,dc=com"
}

The request body will contain a role configuration, for which validation would have been called.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

The plugin should respond with JSON array response for each configuration key that has a validation error

[
  {
   "key": "MemberOf",
   "message": "MemberOf cannot be blank"
  }
]

If any of the input keys have a validation error on them, the plugin is expected to return a list of validation error objects. If the configuration is valid, the plugin should return an empty JSON array.

Search users

If a plugin supports users search, this message must be implemented to lookup for users in an external Authorization Server through GoCD User Summary page.

Request name

go.cd.authorization.search-users

Request body

An search request body

{
  "search_term": "queried string",
  "profiles": {
    "foo-ldap": {
      "Url": "ldap://foo.url"
    },
    "bar-ldap": {
      "Url": "ldap://bar.url"
    }
  }
}

The request body will contain the following JSON elements:

Key Type Description
search_term String The search string entered by the user.
profiles Object This key contains list of <authconfig> configured for plugin.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

The plugin should respond with JSON array of users

[
  {
    "username": "sbanks",
    "display_name": "Sarah Banks",
    "email_id": "sbanks@example.com"
  },
  {
    "username": "pbanks",
    "display_name": "Phillip Banks",
    "email_id": "pbanks@example.com"
  }
]

Plugin should respond with JSON array of users and each user must have following JSON elements in it.

Key Type Description
username String username of user which has to be unique across user base.
display_name String display_name of user which gets displayed on GoCD server. If display_name is not provided then username will be displayed.
email_id String email_id of user

Authorization Server URL

This is a message that a web based plugin should implement. A web based plugin uses an external authorization server for authentication. For this request the plugin should return the URL of the external authorization server to which GoCD redirects the user for authentication.

Request name

go.cd.authorization.authorization-server-url

Request body

The plugin will receive the following JSON body which is a list of all auth configs configured for the plugin —

{
  "auth_configs": [{
    "id": "github_oauth",
    "configuration": {
      "url": "http://git_hub.com",
      "client_id": "jd9no0f",
      "client_secret": "0njfg8fgmfvufv"
    }
  }],
  "authorization_server_callback_url": "http://my_go_server/go/plugin/my_plugin_id/authenticate"
}

Key Type Description
auth_configs Object This key contains list of <authconfig> configured for the plugin.
authorization_server_callback_url String This key contains the GoCD url to which the authorization server should redirect on a successful authentication

Response Body

An example response body:

{
  "authorization_server_url": "http://external_auth_server_url/login?redirect_url=http://my_go_server/go/plugin/my_plugin_id/authenticate&client_id=hdfjh3r&client_secret=vbvdv1493",
  "auth_session": {
    "key": "value"
  }
}

The response body will contain the following JSON elements:

Key Type Description
authorization_server_url String The external authorization server URL to which GoCD redirects the user for authentication.
auth_session Object A flat object/dictionary with string keys and values that will be stored against the users session and passed back to the plugin when fetching the access token. (optional)

The plugin is expected to return status 200 if it can understand the request.

The auth_session field can be used to store some state against the user who is initiating the login flow. This state, if provided, will then be subsequently passed back to the plugin when fetching an access token. The main purpose for this is to allow the plugin to later verify that the user who initiated the login flow is the same one who is completing it in redirect-based authentication flows.

For example, a plugin could store a random value which it expects the authorization server to reflect back to the GoCD server in HTTP request parameters after the user has authenticated with the external server later redirecting to the GoCD server. During Fetch Access Token the plugin can compare contents of the auth_session to the request parameters, or use them in fetching the access token to provide additional security mitigations.

A specific example within redirect flows are the OAuth2 state and the OIDC nonce parameters which if supported by the authorization server/identity provider are generally generated by the client relying party (GoCD in this case) prior to redirecting to the external server, and then validated after redirect back to the relying party. For state this would be done by comparing a generated value stored within the auth_session pre-redirect to a request parameter post-redirect. For the nonce by storing within the auth_session and then comparing to that within the returned ID token by the external authorization server.

Fetch Access Token

This is a message that a web based plugin should implement. In case of web based authentication a user is authenticated by an external authorization server. On successful authentication, the authorization server should redirect to GoCD endpoint returned by authorization server url request. We would refer to these requests as pre-authenticated requests. Depending upon the authorization server, the pre-authenticated requests can contain user information either in HTTP header or request params. GoCD, upon receiving a pre-authenticated request, would make the fetch access token request to the plugin by passing all the user information provided by the authorization server. The plugin in turn should exchange this information with the authorization server to request for an access token to make subsequent requests on behalf of the user.

Request name

go.cd.authorization.fetch-access-token

Request body

The plugin will receive the following JSON body which is a list of all auth configs configured for the plugin —

{
  "auth_configs": [{
    "id": "github_oauth",
    "configuration": {
      "url": "http://git_hub.com",
      "client_id": "jd9no0f",
      "client_secret": "0njfg8fgmfvufv"
    }
  }],
  "auth_session": {
    "key": "value"
  }
}

Key Type Description
auth_configs Object This key contains list of <authconfig> configured for the plugin.
role_configs Object This key contains list of <roleconfig> configured for the plugin.
auth_session Object This key contains a flat object/dictionary of string keys and values that was previously provided during the get authentication server URL exchange. Will be empty if nothing was earlier supplied, and can be ignored.

See get authentication server URL for an example of how auth_session might be used for additional validation within these subsequent calls.

Request parameters

Request parameters would contain all request parameters sent by the external authorization server to GoCD.

Request headers

Request headers would contain all the HTTP request headers sent by the external authorization server to GoCD.

Response Body

The response should be a JSON with the necessary information required by the plugin to make any subsequent calls to the authorization server on behalf of the user. GoCD would pass the returned json as credentials for the Authenticate User request.

The plugin is expected to return status 200 if it can understand the request.

Is Valid User

This is a message that a plugin should implement, in case of access token based authentication. User can configure access token after authenticating him/her self using the plugin. The plugin will receive this message when a user is trying to access API(s) via access token created using the same plugin.

Request name

go.cd.authorization.is-valid-user

Request body

The plugin will receive the following JSON body which is a list of all auth configs configured for the plugin —

{
  "auth_config": {
    "configuration": {
      "key1": "value2"
    },
    "id": "ldap"
  },
  "username": "Bob"
}

Key Type Description
auth_config Object This key represents the <authconfig> using which token is created.
username String This key represents username of the user for which this validation request has been made.

Request parameters

The server will not provide any parameters.

Request headers

The server will not provide any headers.

Response Body

The plugin is expected to return status 200 if the user belongs to specified username is still valid.

Get User Roles

This is a message that a web based plugin should implement, in case the plugin supports can_get_user_roles capability. The plugin will receive this message when GoCD requires to reauthorize the user.

Request name

go.cd.authorization.get-user-roles

Request body

The plugin will receive the following JSON body which is a list of all auth configs configured for the plugin —

{
  "auth_config": {
    "configuration": {
      "key1": "value2"
    },
    "id": "ldap"
  },
  "role_configs": [
    {
      "auth_config_id": "ldap",
      "configuration": {
        "key2": "value2"
      },
      "name": "super-admin"
    }
  ],
  "username": "Bob"
}

Key Type Description
auth_config Object This key represents <authconfig> configured for the plugin.
role_configs Object This key contains list of <roleconfig> configured for the <authconfig>.
username String This key represents username of the user for which this request has been made.

Request parameters

The server will not provide any parameters.

Request headers

The server will not provide any headers.

Response Body

The response should be a JSON array of String which represents role names assigned to the given user.

The plugin is expected to return status 200 if it can understand the request.

Requests to the GoCD server

The plugin may make following requests to the server using GoApplicationAccessor#submit(GoApiRequest)

Invalidate Users Cache

This message allows a plugin invalidate logged in user session in GoCD.

With authorization plugins a user is authenticated using an external authorization server, upon successful authentication GoCD creates a looged in session for the user. Changes on the external authorization server like removing a user or change of role needs to be notified to GoCD. This message can be used by plugins to trigger a re-authentication of users in GoCD.

Request name

go.processor.authorization.invalidate-cache

Request version

The request version must be set to 1.0.

Request body

The server will not parse a request body.

Response code

The plugin is expected to return status 200 if it can understand the request.

The server will not provide any response body.

Get Server Info

This messages allows a plugin to query the server to get some metadata about the server.

Available since v17.9.0.

Request name

go.processor.server-info.get

Request version

The request version must be set to 1.0.

Request body

The plugin should not provide a request body.

Response code

The server is expected to return status 200 if it could process the request.

Response Body

The plugin will provide a server info object.

An example response body:

{
  "server_id": "df0cb9be-2696-4689-8d46-1ef3c4e4447c",
  "site_url": "http://example.com:8153/go",
  "secure_site_url": "https://example.com:8154/go"
}

Add Server Health Messages

import com.thoughtworks.go.plugin.api.*;
import com.thoughtworks.go.plugin.api.annotation.Extension;
import com.thoughtworks.go.plugin.api.logging.Logger;
import com.thoughtworks.go.plugin.api.request.*;
import com.thoughtworks.go.plugin.api.response.*;
import com.google.gson.Gson;
import java.util.*;

@Extension
public class LdapAuthorizationPlugin implements GoPlugin {
  private GoApplicationAccessor accessor;
  public static final Logger LOG = Logger.getLoggerFor(LdapAuthorizationPlugin.class);

  public void initializeGoApplicationAccessor(GoApplicationAccessor accessor) {
    this.accessor = accessor;
  }

  public GoPluginIdentifier pluginIdentifier() {
    return new GoPluginIdentifier("authorization", Arrays.asList("1.0"));
  }

  private void addErrorsAndWarnings() {
    Gson gson = new Gson();
    // create a request
    DefaultGoApiRequest request = new DefaultGoApiRequest(
      "go.processor.server-health.add-messages",
      "1.0",
      pluginIdentifier()
    );

    // set the request body
    List<Map<String, String>> messages = new ArrayList<>();

    Map<String, String> message1 = new HashMap<>();
    message1.put("type", "warning");
    message1.put("message", "A warning message from the plugin.");

    Map<String, String> message2 = new HashMap<>();
    message2.put("type", "error");
    message2.put("message", "An error message from the plugin.");

    messages.add(message1);
    messages.add(message2);

    request.setRequestBody(gson.toJson(messages));

    // submit the request
    GoApiResponse response = accessor.submit(request);

    // check status
    if (response.responseCode() != 200) {
      LOG.error("The server sent an unexpected status code " + response.responseCode() + " with the response body " + response.responseBody());
    }
  }
}

This message allows a plugin to add error and warning messages to be shown in GoCD. Any previous messages sent by the plugin will be cleared and replaced with the newly specified messages (or cleared if the body is an empty list).

Available since v18.3.0.

Request name

go.processor.server-health.add-messages

Request version

The request version must be set to 1.0.

Request body

An example request body:

[
  {
    "type": "warning",
    "message": "A warning message from the plugin."
  },
  {
    "type": "error",
    "message": "An error message from the plugin."
  }
]

Must be a JSON array made up of JSON objects as described below:

Key Type Description
type String Should be either warning or error, corresponding to the type of message to be shown.
message String A message to be shown in the “Errors and Warnings” box.

Response code

The server is expected to return status 200 if it could process the request. It is expected to return status 500 if it failed to process the request.

Response Body

An example response body for a failure:

{
  "message": "An error occurred ..."
}

The server will respond with a single JSON object with an error message with the key message, if it is unable to process the request. If successful, the response body will be empty.

Request/Response JSON Objects

The Settings View Object

Here’s an example of the settings view object:

{
  "template": "<div class=\"form_item_block\">...</div>"
}

Attribute Type Description
template String A string containing an HTML AngularJS based view.

The Image Object

Here’s an example of the image object:

{
  "content_type": "image/svg+xml",
  "data": "...."
}

Attribute Type Description
content_type String A valid content type for the image. Please make sure the content type is supported by most browsers.
data String A base-64 encoded (single-line non-chunking) byte array of the byte-sequence that composes the image.

The Validation Error Object

Here’s an example of the validation error object:

[
  {
    "key": "email_address",
    "message": "Email address is invalid"
  },
  {
    "key": "password",
    "message": "Password must be provided"
  }
]

Attribute Type Description
key String The name of configuration key that has an error.
message String The error message associated with that key.

The Verify Connection Error Object

Here’s an example of the verify connection error object:

[
  {
    "key": "",
    "message": "Failed to authenticate `ManagerDN`."
  }
]

Attribute Type Description
key String Empty string.
message String Connection check failure message.

The server info object

Here’s an example of the server info object:

{
  "server_id": "df0cb9be-2696-4689-8d46-1ef3c4e4447c",
  "site_url": "http://example.com:8153/go",
  "secure_site_url": "https://example.com:8154/go"
}

Attribute Type Description
server_id String This contains a unique identifier for this server.
site_url String This contains the site url configured for this server.
secure_site_url String This contains the secure site url configured for this server.