---
title: "Security and governance"
description: "How API Hub controls access: the checks on each request, how access stops, the log, and the responsibilities of the operator."
canonical: security.html
navigation-title: "Security"
---

<a id="overview-security"></a>

<a id="security-and-governance"></a>

# Security and governance

- [All requests pass the same checks](#all-requests-pass-the-same-checks)
- [Two ways to connect](#two-ways-to-connect)
- [How access stops](#how-access-stops)
- [Data protection](#data-protection)
- [The log](#the-log)
- [Your responsibilities](#your-responsibilities)

The access of an application is never more than the access of its backend user.
It is also never more than an administrator selected. This page gives a summary
for a security review. See [Scopes](../usage/scopes.md#usage-scopes) and [Authentication](../usage/authentication.md#usage-authentication)
for the details.

<a id="overview-security-checks"></a>

<a id="all-requests-pass-the-same-checks"></a>

## All requests pass the same checks

```diagram
flow canvas=860 even
  columns 1,1,1,1,1
  gap 32,36
title "An application must pass four checks to access your content"
description "A request passes four checks in sequence: the token, the scopes, the permissions of the backend user and the safeguards for sensitive data. An invalid token returns the status 401. Each other failed check returns the status 403. After all checks, the request reaches the content."

token "Token"
  at 0,0
  eyebrow "Check 1"
  body "App enabled, token valid"
scopes "Scopes"
  at 1,0
  eyebrow "Check 2"
  body "Selected by an admin"
user "Permissions"
  at 2,0
  eyebrow "Check 3"
  body "Of the backend user"
sensitive "Safeguards"
  at 3,0
  eyebrow "Check 4"
  body "Scope for admin tables"
content "Content"
  at 4,0
  eyebrow "Access"
  store
  body "Records and files"
e401 `401`
  at 0,1
  dashed
  body "Token not valid"
e403a `403`
  at 1,1
  dashed
  body "Scope missing"
e403b `403`
  at 2,1
  dashed
  body "No permission"
e403c `403`
  at 3,1
  dashed
  body "No admin scope"

token => scopes
scopes => user
user => sensitive
sensitive => content
token -x e401
scopes -x e403a
user -x e403b
sensitive -x e403c
```

*Each request must pass all checks. The first failed check stops the request. API responses never contain passwords.*

```diagram
matrix canvas=684
title "An administrator selects the access of each app"
description "Four example apps against the scopes that an administrator selected for them. The content import and the editorial assistant can read and change content. The uptime monitoring and the translation service can only read content. No app can do administrative tasks."

column "Read content" group="Access selected by the administrator" sub="content:read"
column "Change content" group="Access selected by the administrator" sub="content:write"
column "Admin tasks" group="Access selected by the administrator" sub="admin"

row "Content import": yes yes no
row "Uptime monitoring": yes no no
row "Editorial assistant": yes yes no
row "Translation service": yes no no

legend yes="allowed" no="not allowed"
```

*Example of four apps. The administrator selects the access for each app, independent of its app type.*

<a id="overview-security-access"></a>

<a id="two-ways-to-connect"></a>

## Two ways to connect

**Static token:** Use this for integrations between servers. The application
uses one backend user. An administrator selects this user. The token does not
expire.

**OAuth 2.0:** Use this for applications with many users. Each person logs in
to TYPO3 and approves the access on a consent screen. This screen shows the
application and the requested access. Access tokens are valid for one hour.

```diagram
sequence canvas=684
title "A person approves the access of an OAuth application"
description "The application sends the person to TYPO3. The person logs in and approves the requested access. TYPO3 sends a code to the application. The application exchanges the code for tokens and calls the API."

lane app "Application"
lane person "Person"
  person
lane typo3 "TYPO3"
phase "Approval"
  app -> person "Asks for access"
  person -> typo3 "Logs in and approves"
  typo3 -> app "Sends a code"
phase "Access"
  app <-> typo3 "Exchanges the code for tokens"
  app => typo3 "Calls the API with the token"
```

*The application does not get the password. It gets a token, and the permissions of the person apply.*

See the [comparison of the app types](../administration/index.md#administration-app-types).

<a id="overview-security-revoke"></a>

<a id="how-access-stops"></a>

## How access stops

Most changes apply on the next request, also to issued tokens.

| Action of the administrator | Result for the application |
| --- | --- |
| Disables the app | `401`, the app is not available |
| Generates a new secret and saves the app | Static token: `401`, the old token is no longer valid. OAuth: the app cannot get new tokens. Issued access tokens stay valid until they expire after one hour. |
| Removes a scope from the app | `403` for all actions that need this scope |
| Disables the backend user an app acts for | `403`, the user has no scopes. This applies to static tokens and to OAuth tokens |
| Changes the TYPO3 encryption key | All issued tokens become invalid |

<a id="overview-security-data"></a>

<a id="data-protection"></a>

## Data protection

- **Location of the data**

  API Hub operates in your TYPO3 installation and needs no additional
  service. The package does not send data to third parties. Connected
  applications get the data that their access allows.
- **Secrets**

  TYPO3 keeps only a SHA-256 digest of an app secret. TYPO3 shows the secret
  only one time, when you generate it.
- **Passwords**

  Records from the API do not contain passwords or password hashes.
  An application with the necessary permissions can set a password.
- **Administrator data**

  Tables for administrators, for example backend users, also need the scope
  `admin`. Only an app whose backend user is an administrator can use this
  scope.
- **Errors**

  The response to an unexpected error does not contain internal details. It
  contains a request ID. Use this ID to find the log entry.

<a id="overview-security-audit"></a>

<a id="the-log"></a>

## The log

TYPO3 writes changes of records and files to the system log, as in the backend.

> [!WARNING]
> The log shows the **backend user**, not the app. If apps use the same
> backend user, the log cannot identify the app. TYPO3 does not write read
> requests to the system log.

> [!TIP]
> Create one backend user for each static token app. Give this user only the
> necessary permissions. To record all requests, use the access log of your
> web server.

<a id="overview-security-operator"></a>

<a id="your-responsibilities"></a>

## Your responsibilities

Include these items in your review:

| Topic | What to plan |
| --- | --- |
| Your own code | The TYPO3 Company is the manufacturer of the Suite components. You are responsible for your extensions, your actions and the integration in your project. |
| Transport encryption | Use only HTTPS for the API. Each request contains a token. |
| Rate limits | API Hub has no rate limits. If necessary, set them on your web server or in a reverse proxy. |
| Static tokens | They do not expire. Keep them in a secret store. Define when you replace them. |
| Administrators | An app with an administrator as backend user can access all data. Use backend users with limited permissions. |
| Periodic review | Review the list of apps at a fixed interval. Disable the apps that are not in use. |

[Status and adoption](status.md)

[Available scopes](../usage/scopes.md)
