sync a58faaa refactor(authz)
This commit is contained in:
@@ -29,6 +29,7 @@ MODEL OPA (authz.yml -> data.json):
|
||||
matrix [--schema <s>] matriks role x tabel (s=select w=write d=ddl)
|
||||
show role|user|table <nama> detail satu objek
|
||||
grant add|set|remove <role> <schema.table> [--caps a,b] [--columns x,y|*]
|
||||
grant add <role> '<schema>.*' [--caps a,b] # seluruh tabel di schema (mis. gold.*)
|
||||
role add|remove <nama> [--superuser] [--force]
|
||||
user assign|unassign <svc> <role> service account -> role (model)
|
||||
catalog list|add|rename <baru> kelola catalog (rename ikut berkas Trino)
|
||||
|
||||
@@ -55,10 +55,10 @@ then ok "data.json identik dengan hasil render"; else bad "data.json berbeda dar
|
||||
|
||||
# ─── B. Policy data-driven ───────────────────────────────────────────────────
|
||||
echo; echo -e "${BLD}B. Policy Rego data-driven${NC}"
|
||||
if grep -q 'data.authz.catalogs' "${REGO}" && grep -q 'data.authz.write_schemas' "${REGO}"; then
|
||||
ok "Rego membaca katalog/schema dari data.authz.*"
|
||||
if grep -q 'data.authz.catalogs' "${REGO}" && grep -q 'schema_grant' "${REGO}"; then
|
||||
ok "Rego data-driven (data.authz.catalogs + schema_grant)"
|
||||
else
|
||||
bad "Rego belum data-driven (data.authz.* tidak ditemukan)"
|
||||
bad "Rego belum data-driven (data.authz.* / schema_grant tidak ditemukan)"
|
||||
fi
|
||||
if grep -qE '"iceberg"' "${REGO}"; then
|
||||
bad "Rego masih meng-hardcode literal \"iceberg\""
|
||||
@@ -86,6 +86,19 @@ case "${out}" in *"caps=[select,write]"*) ok "grant set menimpa caps" ;; *) bad
|
||||
out="$(cli show role data-scientist)"
|
||||
case "${out}" in *"caps=[select]"*) ok "grant remove --caps menyisakan select" ;; *) bad "grant remove gagal: ${out}" ;; esac
|
||||
|
||||
"${CLI}" --model "${M}" grant add data-scientist 'gold.*' --caps select --columns "*" >/dev/null 2>&1
|
||||
out="$(cli show role data-scientist)"
|
||||
case "${out}" in *"gold.*"*) ok "grant tingkat-schema tersimpan (gold.*)" ;; *) bad "grant schema tak tersimpan: ${out}" ;; esac
|
||||
python3 "${DEPLOY_DIR}/lib/authz.py" --model "${M}" --out "${OUT}/d2.json" render >/dev/null 2>&1
|
||||
if python3 -c "import json;d=json.load(open('${OUT}/d2.json'));assert d['roles']['data-scientist']['schema_grants']['gold']['select'] is True"; then
|
||||
ok "render menampilkan schema_grants"
|
||||
else
|
||||
bad "render tak memuat schema_grants"
|
||||
fi
|
||||
"${CLI}" --model "${M}" grant remove data-scientist 'gold.*' >/dev/null 2>&1
|
||||
out="$(cli show role data-scientist)"
|
||||
case "${out}" in *"gold.*"*) bad "grant schema tak terhapus" ;; *) ok "grant schema terhapus" ;; esac
|
||||
|
||||
"${CLI}" --model "${M}" user assign svc_ml data-scientist >/dev/null 2>&1
|
||||
out="$(cli show user svc_ml)"
|
||||
case "${out}" in *"svc_ml: data-scientist"*) ok "user assign bekerja" ;; *) bad "user assign gagal: ${out}" ;; esac
|
||||
@@ -181,12 +194,43 @@ for i, (_, want) in enumerate(base_cases):
|
||||
print(f" keputusan[{i}] -> {got or '(undefined)'} (harap {want})")
|
||||
if got != want:
|
||||
fails += 1
|
||||
|
||||
# Blok luas data-driven: op di LUAR op_caps (simulasi level-kolom UPDATE/MERGE)
|
||||
extra = [
|
||||
(tin("UpdateColumns", "iceberg", "bronze", "orders", ["id"], "u", ["data-engineer"]), "true"),
|
||||
(tin("UpdateColumns", "iceberg", "gold", "orders_gold", ["id"], "u", ["data-analyst"]), "false"),
|
||||
(tin("UpdateColumns", "iceberg", "other", "x", ["id"], "u", ["data-engineer"]), "false"),
|
||||
]
|
||||
te = build(extra)
|
||||
for i, (_, want) in enumerate(extra):
|
||||
got = ev(te, i)
|
||||
print(f" luas[{i}] -> {got or '(undefined)'} (harap {want})")
|
||||
if got != want:
|
||||
fails += 1
|
||||
|
||||
tr = build(ren_cases, {"authz": {"catalogs": ["lakehouse"], "write_schemas": ["bronze", "silver", "gold"]}})
|
||||
for i, (_, want) in enumerate(ren_cases):
|
||||
got = ev(tr, i)
|
||||
print(f" rename[{i}] -> {got or '(undefined)'} (harap {want})")
|
||||
if got != want:
|
||||
fails += 1
|
||||
|
||||
# Grant tingkat-schema: data-analyst dapat 'gold.*' (select)
|
||||
roles = json.loads((opa / "data.json").read_text())["roles"]
|
||||
roles["data-analyst"]["schema_grants"] = {"gold": {"select": True, "columns": "*"}}
|
||||
sch_cases = [
|
||||
(tin("SELECTFROMCOLUMNS", "iceberg", "gold", "orders_gold", ["id"], "u", ["data-analyst"]), "true"),
|
||||
(tin("SELECTFROMCOLUMNS", "iceberg", "gold", "brand_new_table", ["id"], "u", ["data-analyst"]), "true"),
|
||||
(tin("SELECTFROMCOLUMNS", "iceberg", "bronze", "orders", ["id"], "u", ["data-analyst"]), "false"),
|
||||
(tin("SELECTFROMCOLUMNS", "iceberg", "silver", "orders_silver", ["order_date"], "u", ["data-analyst"]), "false"),
|
||||
(tin("FILTERTABLES", "iceberg", "gold", "whatever", [], "u", ["data-analyst"]), "true"),
|
||||
]
|
||||
ts = build(sch_cases, {"roles": roles})
|
||||
for i, (_, want) in enumerate(sch_cases):
|
||||
got = ev(ts, i)
|
||||
print(f" schema[{i}] -> {got or '(undefined)'} (harap {want})")
|
||||
if got != want:
|
||||
fails += 1
|
||||
sys.exit(1 if fails else 0)
|
||||
PY
|
||||
then ok "policy OPA: perilaku dasar + ganti catalog lewat data (via docker)"
|
||||
|
||||
Reference in New Issue
Block a user