フィールドおよびドキュメントレベルのセキュリティの設定
データストリームまたはインデックス内のデータへのアクセスを制御するには、ロールにフィールドおよびドキュメントレベルのセキュリティ権限を追加します。フィールドレベルのセキュリティ権限は、ドキュメント内の特定のフィールドへのアクセスを制限します。ドキュメントレベルのセキュリティ権限は、特定のドキュメントへのアクセスを制限します。
ドキュメントおよびフィールドレベルのセキュリティは、現在、読み取り専用の特権アカウントで機能することを意図しています。データストリームまたはインデックスに対してドキュメントおよびフィールドレベルのセキュリティが有効になっているユーザーは、書き込み操作を行うべきではありません。
ロールは、インデックスごとにフィールドおよびドキュメントレベルの権限を定義できます。フィールドレベルの権限を指定しないロールは、すべてのフィールドへのアクセスを許可します。同様に、ドキュメントレベルの権限を指定しないロールは、インデックス内のすべてのドキュメントへのアクセスを許可します。
ユーザーに複数のロールを割り当てる際は、意図しない広範なアクセスを付与しないように注意してください。各ユーザーは、データストリームまたはインデックスごとに単一のフィールドレベルおよびドキュメントレベルの権限セットを持っています。ドキュメントおよびフィールドレベルのセキュリティを持つ複数のロールを参照してください。
ドキュメントおよびフィールドレベルのセキュリティを持つ複数のロール
ユーザーは多くのロールを持つことができ、各ロールは同じデータストリームまたはインデックスに対して異なる権限を定義できます。このシナリオにおけるドキュメントおよびフィールドレベルのセキュリティの動作を理解することが重要です。
ドキュメントレベルのセキュリティは、ユーザーが持つ各ロールを考慮し、特定のデータストリームまたはインデックスに対する各ドキュメントレベルのセキュリティクエリを「OR」で組み合わせます。これは、ドキュメントが返されるためには、ロールクエリのいずれかが一致する必要があることを意味します。たとえば、あるロールがドキュメントレベルのセキュリティなしでインデックスへのアクセスを許可し、別のロールがドキュメントレベルのセキュリティでアクセスを許可する場合、ドキュメントレベルのセキュリティは適用されません。両方のロールを持つユーザーは、インデックス内のすべてのドキュメントにアクセスできます。
フィールドレベルのセキュリティは、ユーザーが持つ各ロールを考慮し、各データストリームまたはインデックスに対してリストされたすべてのフィールドを単一のセットにまとめます。たとえば、あるロールがフィールドレベルのセキュリティなしでインデックスへのアクセスを許可し、別のロールがフィールドレベルのセキュリティでアクセスを許可する場合、そのインデックスに対してフィールドレベルのセキュリティは適用されません。両方のロールを持つユーザーは、インデックス内のすべてのフィールドにアクセスできます。
たとえば、role_a
がindex1
のドキュメントのaddress
フィールドへのアクセスのみを許可する場合、ドキュメントの制限は指定されていません。逆に、role_b
はindex1
のドキュメントのサブセットへのアクセスを制限しますが、フィールドの制限は指定されていません。ユーザーに両方のロールを割り当てると、role_a
はユーザーにすべてのドキュメントへのアクセスを許可し、role_b
はユーザーにすべてのフィールドへのアクセスを許可します。
ドキュメントとフィールドの両方へのアクセスを制限する必要がある場合は、インデックスによってドキュメントを分割することを検討してください。
ロールクエリのテンプレート化
ロールを作成する際に、ドキュメントレベルのセキュリティ権限を定義するクエリを指定できます。オプションで、ロールクエリ内でMustacheテンプレートを使用して、現在認証されているユーザーのユーザー名をロールに挿入できます。テンプレートやスクリプトをサポートするElasticsearchの他の場所と同様に、インライン、ストレージ、またはファイルベースのテンプレートを指定し、カスタムパラメータを定義できます。現在認証されているユーザーの詳細には、_user
パラメータを介してアクセスします。
たとえば、次のロールクエリは、現在認証されているユーザーのユーザー名を挿入するためにテンプレートを使用しています:
Python
resp = client.security.put_role(
name="example1",
indices=[
{
"names": [
"my-index-000001"
],
"privileges": [
"read"
],
"query": {
"template": {
"source": {
"term": {
"acl.username": "{{_user.username}}"
}
}
}
}
}
],
)
print(resp)
Js
const response = await client.security.putRole({
name: "example1",
indices: [
{
names: ["my-index-000001"],
privileges: ["read"],
query: {
template: {
source: {
term: {
"acl.username": "{{_user.username}}",
},
},
},
},
},
],
});
console.log(response);
コンソール
POST /_security/role/example1
{
"indices" : [
{
"names" : [ "my-index-000001" ],
"privileges" : [ "read" ],
"query" : {
"template" : {
"source" : {
"term" : { "acl.username" : "{{_user.username}}" }
}
}
}
}
]
}
| プロパティ | 説明 |
| :-- | :-- |
| `````_user.username````` | 現在認証されているユーザーのユーザー名。 |
| `````_user.full_name````` | 指定されている場合、現在認証されているユーザーのフルネーム。 |
| `````_user.email````` | 指定されている場合、現在認証されているユーザーのメールアドレス。 |
| `````_user.roles````` | 関連付けられている場合、現在認証されているユーザーのロール名のリスト。 |
| `````_user.metadata````` | 指定されている場合、現在認証されているユーザーのカスタムメタデータを保持するハッシュ。 |
カスタムユーザーメタデータにもアクセスできます。たとえば、ユーザーメタデータに`````group_id`````を保持している場合、ドキュメント内の`````group.id`````フィールドに基づいてドキュメントレベルのセキュリティを適用できます:
#### Python
``````python
resp = client.security.put_role(
name="example2",
indices=[
{
"names": [
"my-index-000001"
],
"privileges": [
"read"
],
"query": {
"template": {
"source": {
"term": {
"group.id": "{{_user.metadata.group_id}}"
}
}
}
}
}
],
)
print(resp)
`
Js
const response = await client.security.putRole({
name: "example2",
indices: [
{
names: ["my-index-000001"],
privileges: ["read"],
query: {
template: {
source: {
term: {
"group.id": "{{_user.metadata.group_id}}",
},
},
},
},
},
],
});
console.log(response);
コンソール
POST /_security/role/example2
{
"indices" : [
{
"names" : [ "my-index-000001" ],
"privileges" : [ "read" ],
"query" : {
"template" : {
"source" : {
"term" : { "group.id" : "{{_user.metadata.group_id}}" }
}
}
}
}
]
}
メタデータフィールドがオブジェクトまたは配列を含む場合、{{#toJson}}parameter{{/toJson}}
関数を使用してアクセスできます。
Python
resp = client.security.put_role(
name="example3",
indices=[
{
"names": [
"my-index-000001"
],
"privileges": [
"read"
],
"query": {
"template": {
"source": "{ \"terms\": { \"group.statuses\": {{#toJson}}_user.metadata.statuses{{/toJson}} }}"
}
}
}
],
)
print(resp)
Js
const response = await client.security.putRole({
name: "example3",
indices: [
{
names: ["my-index-000001"],
privileges: ["read"],
query: {
template: {
source:
'{ "terms": { "group.statuses": {{#toJson}}_user.metadata.statuses{{/toJson}} }}',
},
},
},
],
});
console.log(response);
コンソール
POST /_security/role/example3
{
"indices" : [
{
"names" : [ "my-index-000001" ],
"privileges" : [ "read" ],
"query" : {
"template" : {
"source" : "{ \"terms\": { \"group.statuses\": {{#toJson}}_user.metadata.statuses{{/toJson}} }}"
}
}
}
]
}
セキュリティ詳細を追加するためのドキュメントの前処理
ユーザーが自分のドキュメントのみを読み取ることを保証するために、ドキュメントレベルのセキュリティを設定することが理にかなっています。このシナリオでは、各ドキュメントに関連付けられたユーザー名またはロール名が必要です。この情報は、ドキュメントレベルのセキュリティのためのロールクエリで使用できます。これは、セキュリティユーザープロセッサの設定インジェストプロセッサが役立つ状況です。
ドキュメントレベルのセキュリティは、書き込みAPIには適用されません。同じデータストリームまたはインデックスを使用する各ユーザーに対して一意のIDを使用する必要があります。そうしないと、他のユーザーのドキュメントを上書きする可能性があります。インジェストプロセッサは、インデックスされているドキュメントに現在認証されているユーザーのプロパティを追加するだけです。
セキュリティユーザープロセッサの設定は、現在認証されているユーザーからのユーザー関連の詳細(username
、roles
、email
、full_name
、およびmetadata
)を現在のドキュメントに添付します。データをインジェストパイプラインでインデックスすると、ユーザーの詳細が自動的にドキュメントに添付されます。認証資格情報がAPIキーである場合、APIキーid
、name
、およびmetadata
(存在し、空でない場合)もドキュメントに添付されます。
詳細については、インジェストパイプラインおよびセキュリティユーザーの設定を参照してください。
クロスクラスタAPIキーを使用したフィールドおよびドキュメントレベルのセキュリティ
クロスクラスタAPIキーは、リモートクラスタへのリクエストを認証するために使用できます。search
パラメータは、クロスクラスタ検索の権限を定義します。replication
パラメータは、クロスクラスタレプリケーションの権限を定義します。
replication
は、フィールドまたはドキュメントレベルのセキュリティをサポートしていません。search
は、フィールドおよびドキュメントレベルのセキュリティをサポートしています。
ドキュメントおよびフィールドレベルのセキュリティを持つ複数のロールで説明されているのと同様の理由から、search
パラメータにドキュメントまたはフィールドレベルのセキュリティが定義されている場合、search
およびreplication
パラメータの両方を持つ単一のクロスクラスタAPIキーを作成することはできません。
これらのパラメータの両方を使用する必要があり、search
パラメータに対してドキュメントまたはフィールドレベルのセキュリティを定義する必要がある場合は、search
パラメータを使用する1つのクロスクラスタAPIキーと、replication
パラメータを使用する別のクロスクラスタAPIキーを作成してください。また、同じクラスタへの2つの異なるリモート接続を設定する必要があります。各接続には、適切なクロスクラスタAPIキーを使用します。