# Heroku

Connecting Heroku gives SureCloud read access to your Heroku Enterprise account's teams, applications, members, pipeline configurations, and audit log events. SureCloud monitors team membership to identify accounts with excessive permissions, checks application configuration for security-relevant settings such as SSL enforcement and environment variable exposure, verifies that add-ons handling sensitive data are restricted to appropriate applications, and collects audit log events to provide evidence of administrative and deployment activity. This provides continuous evidence that your Heroku environment is governed and that access to production applications is appropriately controlled.

{% hint style="info" %}
SureCloud connects to Heroku using a Direct Authorization token (OAuth token) from a dedicated service account. Heroku supports OAuth 2.0 for third-party applications but the Direct Authorization flow — which generates a long-lived token tied to a specific user account — is the recommended method for system integrations.
{% endhint %}

## Authentication and setup

{% stepper %}
{% step %}

#### Create a dedicated service account

In Heroku, create a dedicated account for SureCloud (e.g. `surecloud-ccm@yourcompany.com`). Add this account to your Heroku Enterprise team with the **Member** role — this provides read access to apps and resources without admin-level write permissions.

For audit log access, the account must hold the **Admin** role on the Enterprise Account (not team-level admin). If audit log evidence is required, assign the account the Enterprise **Viewer** role at the account level.

{% hint style="info" %}
Heroku Enterprise distinguishes between **Enterprise Account** roles (Admin, Viewer, Member) and **Team** roles (Admin, Member, Collaborator). SureCloud requires at minimum Team **Member** access. Audit log access requires Enterprise Account **Viewer** or above.
{% endhint %}
{% endstep %}

{% step %}

#### Generate an authorisation token

Log in to the Heroku CLI as the `surecloud-ccm` account and run:

```bash
heroku authorizations:create --description "SureCloud CCM" --expires-in 0
```

The `--expires-in 0` flag creates a non-expiring token. Copy the **Token** value from the output.

Alternatively, generate the token via the Heroku Dashboard: navigate to **Account Settings → Authorizations → Create Authorization**, set the description to `SureCloud CCM`, leave the expiry blank for a non-expiring token, and copy the token.

{% hint style="warning" %}
Although Heroku supports non-expiring tokens, rotate this token every 90 days as a security best practice. Revoke the old authorisation and generate a new one, then update the value in **SureCloud → Integrations → Heroku → Edit Connection**.
{% endhint %}
{% endstep %}

{% step %}

#### Enter credentials in SureCloud

In SureCloud, navigate to **Integrations → Heroku → Connect** and provide:

* **Heroku API token**
* **Enterprise account name** (the slug identifier for your Enterprise account, visible in the Heroku Dashboard URL)

Click **Test Connection**, then **Save**.
{% endstep %}
{% endstepper %}

## Endpoints

| API Call                                                   | Use Case                                                                                 |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `GET /enterprise-accounts/{account_id}/members`            | Enumerate Enterprise account members and their roles                                     |
| `GET /teams`                                               | List all teams in the Enterprise account                                                 |
| `GET /teams/{team_id}/members`                             | Read team membership and role assignments                                                |
| `GET /teams/{team_id}/apps`                                | Enumerate applications in each team                                                      |
| `GET /apps/{app_id}`                                       | Read application configuration including maintenance mode, stack, and region             |
| `GET /apps/{app_id}/config-vars`                           | Read the names (not values) of environment variables to detect sensitive config exposure |
| `GET /apps/{app_id}/ssl-endpoints`                         | Verify SSL endpoint configuration for production applications                            |
| `GET /apps/{app_id}/add-ons`                               | Enumerate add-ons attached to each application                                           |
| `GET /pipelines`                                           | Enumerate deployment pipelines and their stage configuration                             |
| `GET /enterprise-accounts/{account_id}/audit-trail-events` | Retrieve Enterprise audit trail events for administrative and deployment activity        |

{% hint style="warning" %}
SureCloud reads environment variable **names only** from the `/config-vars` endpoint — never their values. This allows SureCloud to detect the presence of potentially sensitive configuration keys (e.g. credentials named `DATABASE_URL`, `AWS_SECRET_ACCESS_KEY`) without exposing the actual secret values.
{% endhint %}

## Pagination

The Heroku Platform API uses range-based pagination via the `Range` and `Next-Range` headers. When a response is paginated, the `Next-Range` response header contains the value to pass as the `Range` request header in the next call. SureCloud iterates until no `Next-Range` header is present.

```
Range: id ..; max=1000;
Next-Range: id abc123..; max=1000; order=asc
```

SureCloud requests up to 1,000 records per page using `max=1000`.

## Required permissions

| Role   | Scope                    | Purpose                                             |
| ------ | ------------------------ | --------------------------------------------------- |
| Member | Team level               | Read apps, add-ons, config var names, and pipelines |
| Viewer | Enterprise Account level | Read enterprise member list and audit trail events  |

The Enterprise Account **Viewer** role is only required if audit log collection is needed. Team-only access is sufficient for application and access configuration data.

## Polling frequency

| Data type                             | Collection interval |
| ------------------------------------- | ------------------- |
| Team and application inventory        | 24 hours            |
| Team membership and roles             | 24 hours            |
| Application configuration and add-ons | 24 hours            |
| Enterprise audit trail events         | 6 hours             |

## Troubleshooting

<details>

<summary>Audit trail events are not appearing</summary>

Heroku Enterprise audit trail access requires the service account to hold the **Viewer** (or higher) role on the Enterprise Account, not just team-level membership. If audit events are absent, confirm the `surecloud-ccm` account has an Enterprise Account-level role in **Heroku Dashboard → Enterprise → \[Account] → Members**.

</details>

<details>

<summary>Applications from some teams are not visible in SureCloud</summary>

The service account must be a member of each team whose applications SureCloud should monitor. Team membership is not inherited from Enterprise Account membership.

Add the `surecloud-ccm` account to each relevant team in **Heroku Dashboard → \[Team] → Members → Add member**.

</details>

<details>

<summary>Config var names are returning as empty for some applications</summary>

The `/apps/{app_id}/config-vars` endpoint returns a 403 if the service account does not have at least **Member** access on that specific application. In Heroku, apps can be owned by a team but collaborators may have restricted access at the app level.

Confirm the `surecloud-ccm` account has at least **Member** or **Collaborator** access on all target applications via **Heroku Dashboard → \[App] → Access**.

</details>

<details>

<summary>Token is being rejected despite being newly generated</summary>

Heroku Direct Authorization tokens are tied to the generating account. If the `surecloud-ccm` account has been deactivated, had its password changed (which invalidates existing tokens), or has been removed from the Enterprise account, all tokens for that account will stop working.

Confirm the account is active and still a member of the Enterprise account. If the account was removed and re-added, generate a new authorisation token and update it in **SureCloud → Integrations → Heroku → Edit Connection**.

</details>

<a href="https://devcenter.heroku.com/articles/platform-api-reference" class="button secondary">Heroku Platform API reference</a> <a href="https://devcenter.heroku.com/articles/oauth" class="button secondary">Heroku OAuth and authorisations documentation</a>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://surecloud.gitbook.io/surecloud-docs/integrations/ccm-and-evidence-collection-integrations/heroku.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
