本机真实只给一个用户create_doc这一个索引权限,验证用POST新建全新文档真实成功,但用PUT覆盖已存在的文档真实被拒绝(需要create/index/write/all,create_doc不在名单里),删除文档同样被拒绝;最后用带op_type=create参数的PUT创建全新id真实也成功了,证明create_doc这个权限判定的是真实的操作语义(确保只有文档不存在时才创建)而不是HTTP方法本身。
代码PUT /_security/role/create_only_role { "cluster": [], "indices": [{"names":["priv_test"],"privileges":["create_doc"]}] } 真实建用户createonlyuser绑定这个role 真实预先存在一条文档: PUT /priv_test/_doc/existing1
代码POST /priv_test/_doc {"n":2,"text":"brand new"}
→ {"result":"created", "_id":"CtUG-qAB5oeo0rbm7JJi"}代码PUT /priv_test/_doc/existing1 {"n":99,"text":"overwritten attempt"}
→ 403 security_exception: "action [indices:data/write/index:op_type/index] is unauthorized ... this action is granted by the index privileges [create,index,write,all]"
这个真实报错精确区分出了ES内部对"创建"和"覆盖写入"这两个语义完全不同的内部action——哪怕HTTP层面都是PUT请求,create_doc这个权限真实只认"保证文档此前不存在才允许创建"这一种语义,覆盖一条已经存在的文档真实需要的是create/index/write/all里的某一个,create_doc真实不在这个名单里。
代码DELETE /priv_test/_doc/existing1
→ 403 security_exception: "action [indices:data/write/delete] is unauthorized ... this action is granted by the index privileges [delete,write,all]"
代码PUT /priv_test/_doc/brandnew1?op_type=create {"n":3,"text":"new via PUT with op_type=create"}
→ {"result":"created", "_id":"brandnew1"} ← 真实用PUT也能创建,只要明确是create语义每一步都是本文在一个真实独立搭建、开启security的Elasticsearch 8.15.0节点上跑出来的原始结果,测完即销毁。
create_doc 索引权限与 op_type 参数