# PostgreSQL 認可

拡張認可は、PostgreSQLとの統合による認可検証をサポートします。

::: tip 注意

PostgreSQL認可は、EMQX Serverlessのデプロイメントではサポートされていません。

:::

## テーブル構造とクエリ文

PostgreSQLオーソライザーは、複数テーブルの結合クエリやビューからのクエリを含む任意のテーブル構造をサポートします。ユーザーはクエリSQLテンプレートを提供する必要があり、クエリ結果には以下のフィールドを含める必要があります。

- `permission`：操作権限を指定し、値は `allow` または `deny`。
- `action`：現在のルールが適用される操作を指定し、値は `publish`、`subscribe`、`all` のいずれか。
- `topic`：現在のルールが適用されるトピックを指定し、トピックフィルターやトピックプレースホルダーを使用可能。
- `qos`：（任意）ルールが適用されるメッセージのQoSを指定し、値は `0`、`1`、`2` または複数のQoSをカンマ区切りで指定可能（例：`0,1`）。デフォルトはすべてのQoSレベル。
- `retain`：（任意）現在のルールが保持メッセージのパブリッシュを許可するかを指定し、値は `0`、`1`。デフォルトは保持メッセージを許可。

テーブル構造の例：

```sql
CREATE TABLE mqtt_acl(
  id serial PRIMARY KEY,
  username text NOT NULL,
  permission text NOT NULL,
  action text NOT NULL,
  topic text NOT NULL,
  qos tinyint,
  retain tinyint
);
CREATE INDEX mqtt_acl_username_idx ON mqtt_acl(username);
```

::: tip

上記の例ではインデックスを作成しています。システム内に大量の権限データがある場合は、クエリに使用するテーブルを最適化し、有効なインデックスを利用して多数の接続時のデータ検索速度を向上させ、EMQXの負荷を軽減してください。

:::

ユーザー `emqx_u` に対し、トピック `t/1` へのパブリッシュを禁止するルールの例：

```sql
postgres=# INSERT INTO mqtt_acl(username, permission, action, topic) VALUES ('emqx_u', 'deny', 'publish', 't/1');
INSERT 0 1
```

対応する設定パラメータは以下の通りです。

```bash
query = "SELECT permission, action, topic, qos, retain FROM mqtt_acl WHERE username = ${username}"
```

## PostgreSQL認可の設定

デプロイメント画面で **Access Control** -> **Authorization** -> **Extended Authorization** をクリックし、**PostgreSQL Authorization** を選択して **Configure** をクリックします。

以下の指示に従い、関連設定を完了してください。

- **Server**：PostgreSQLサーバーのアドレス（host:port）を入力。
- **Database**：PostgreSQLのデータベース名を入力。
- **Username**（任意）：ユーザー名を入力。
- **Password**（任意）：パスワードを入力。
- **Enable TLS**：TLSを有効にするか設定。
- **Connection Pool Size**（任意）：EMQXノードからPostgreSQLデータベースへの同時接続数を整数で指定。デフォルト値は `8`。
- **SQL**：テーブル構造に応じたクエリSQLを記入。詳細は「テーブル構造とクエリ文」を参照。

::: tip

- 現在のデプロイメントが専用版の場合は、VPCピアリング接続を作成する必要があり、サーバーアドレスは内部ネットワークアドレスを指定してください。
- 現在のデプロイメントがBYOC版の場合は、ご利用のパブリッククラウドコンソールでVPCピアリング接続を作成してください。詳細は[BYOCデプロイメントの作成 - VPCピアリング接続の設定](../create/byoc.md#vpc-peering-connection-configuration)を参照。サーバーアドレスは内部ネットワークアドレスを指定してください。
- 「Init resource failure!」が発生した場合は、サーバーアドレスの正確性とセキュリティグループの開放状況を確認してください。

:::
