Metadata-Version: 2.4
Name: rls-persona-tester
Version: 0.1.0
Summary: Automated row-level security (RLS) testing for Power BI & Fabric semantic models.
Author: Green Analytics Ltd
License: RLS Persona Tester — Software License Agreement
        Copyright (c) 2026 Green Analytics Ltd. All rights reserved.
        
        This is a commercial software product. By installing or using it you agree to
        these terms.
        
        1. FREE USE
           The offline demonstration (the "simulated" connector) and the "--preflight"
           diagnostics may be used free of charge for evaluation and internal testing.
        
        2. LICENSED USE
           Running live row-level security tests against any real Power BI or Fabric
           semantic model (any non-"simulated" connector) requires a valid, paid license
           key obtained from Green Analytics Ltd. A license is granted per developer and covers
           that developer's own machines and continuous-integration pipelines.
        
        3. RESTRICTIONS
           You may not resell, sublicense, rent, or redistribute this software or any
           license key; remove or circumvent the license mechanism; or distribute a
           modified copy as your own product. Internal use within your organisation under
           a valid license is permitted.
        
        4. OWNERSHIP
           The software is licensed, not sold. Green Analytics Ltd retains all intellectual
           property rights in it.
        
        5. NO WARRANTY
           THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
           IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
           FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. You are responsible for
           validating results before relying on them for any security, compliance, or
           audit decision.
        
        6. LIMITATION OF LIABILITY
           IN NO EVENT SHALL GREEN ANALYTICS LTD BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
           LIABILITY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, ARISING FROM OR IN
           CONNECTION WITH THE SOFTWARE OR ITS USE.
        
        Contact: via your Polar customer portal.
        
Project-URL: Homepage, https://polar.sh/green-analytics-ltd
Project-URL: Purchase, https://polar.sh/green-analytics-ltd
Keywords: power-bi,fabric,rls,row-level-security,security-testing,dax,semantic-model,business-intelligence,data-governance,ci
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Security
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: yaml
Requires-Dist: pyyaml>=6; extra == "yaml"
Provides-Extra: rest
Requires-Dist: msal>=1.24; extra == "rest"
Requires-Dist: requests>=2.28; extra == "rest"
Dynamic: license-file

# RLS Persona Tester

**Automated row-level security (RLS) testing for Power BI & Fabric semantic models.**

Point it at a published model, declare what each role is *supposed* to see, and it
answers — automatically, in CI, before you ship — the question BI teams still answer
by hand:

> **Does every persona see exactly what it should — no more, no less?**

An RLS leak means the **wrong users see the wrong data**: a security, compliance and
audit failure waiting to surface in front of an auditor or a customer. Today teams
catch it with spare "test accounts" and eyeballing *View as role* — manual, partial,
and easy to skip under deadline. This tool makes it a one-command regression test
that **blocks the release pipeline** when a role leaks.

---

## Install

```bash
pip install rls-persona-tester            # core engine (stdlib only)
pip install 'rls-persona-tester[rest]'    # + live testing against a real model (msal, requests)
```

## Try it in 30 seconds — free, no login

The offline demo runs against a built-in model seeded with two **deliberately buggy
roles**, so you can watch the checks fire:

```bash
rls-test -c examples/demo_config.json
```

```
EMEA_leaky   scope_leak    FAIL   Sees Region outside allowed scope: ['North', 'South']
EMEA_leaky   value_scope   FAIL   Total Sales=800 but allowed scope should total 300
Empty_role   empty_view    FAIL   Role sees no data on any key measure (over-restrictive / broken RLS)
...
[FAIL] 47 checks — 12 failed, 35 passed     # exit 1 → a CI gate would block the deploy
```

Machine-readable and CI outputs:

```bash
rls-test -c examples/demo_config.json -f junit -o results.xml   # JUnit → CI gate
rls-test -c examples/demo_config.json -f json                   # JSON
```

The offline demo and `--preflight` diagnostics are **free forever**.

## Test your real model (licensed)

Run the same checks against a *published* Power BI / Fabric semantic model over the
`executeQueries` REST API — cross-platform (macOS/Linux/Windows/CI), **no Power BI
Desktop, no .NET, no Fabric notebook required**:

```bash
rls-test --preflight -c your_model.json          # connectivity + permission diagnostics (free)
rls-test -c your_model.json --license <KEY>      # live RLS test (licensed)
# or set it once:  export RLS_TESTER_LICENSE_KEY=...
```

A valid license unlocks live runs against your own models. **[Get a license →](https://buy.polar.sh/polar_cl_5wclgy0ITjhod5qBsFC0rx9R8Kx3ENdKcfn3d28tY62)** · **$99/year**.

---

## What it checks

Five checks, from zero-config to declared-intent:

| Check | Needs | Catches |
|---|---|---|
| `empty_view` | nothing | broken / over-restrictive RLS (a role sees nothing) |
| `exceeds_unrestricted` | nothing | hard leak (a role totals more than the whole model) |
| `scope_leak` | role → allowed members | a role sees dimension members outside its lane |
| `value_scope` | role → allowed members | a role's measure ≠ the measure over its allowed scope |
| `reconciliation` | a partition of roles | the roles don't tile the unrestricted total exactly once |

It **passes** a correctly-restricted role and **fails** a leaky one — the complete
regression signal, with a non-zero exit code so release pipelines stop on a leak.

## Config

```json
{
  "connector": "rest",
  "security_table": "Geography",
  "security_column": "Region",
  "measures": ["Total Sales", "Order Count"],
  "connection": { "dataset_id": "<guid>", "group_id": "<workspace-guid>", "client_id": "<app-guid>" },
  "roles": [
    { "name": "North", "as_user": "north-tester@yourco.com", "allowed": ["North"],
      "expected": { "measures": { "Total Sales": 250 }, "visible": ["North"] } }
  ],
  "partition_roles": ["North", "South", "EMEA"]
}
```

- `allowed` — the members this role *should* see on `security_column` (its intent).
- `as_user` — a UPN that is a **member of this role** in the model's Security settings
  (`executeQueries` impersonates a *user*; it can't activate a role by name — that needs XMLA).
- `partition_roles` — roles that together should tile the whole model exactly once.
- `connector: "simulated"` runs the free offline demo with no connection block.

See `examples/` for ready-to-edit configs and `docs/SETUP_FABRIC.md` for the one-time
Fabric/Power BI setup (test users, tenant setting, permissions).

## Knows the Direct Lake + SSO trap

A **Direct Lake model whose source connection uses SSO is incompatible with
`executeQueries` impersonation** — every impersonation fails with `PowerBIEntityNotFound`,
even impersonating the owner. It's a very common Fabric setup and an opaque failure.
This tool **auto-detects that signature and tells you the fix** (bind the Direct Lake
source to a dedicated cloud connection with fixed credentials, SSO off) instead of
leaving you guessing.

## Requirements (live testing)

- Model on Premium / PPU / Fabric capacity (the Fabric trial covers it).
- Tenant setting **"Dataset Execute Queries REST API"** = ON.
- **Build** permission on the model; a test user per role, assigned in Security.
- User auth (MSAL device-code) — service principals aren't allowed on RLS datasets.

## Pricing & license

- **Free:** the offline demo + `--preflight` diagnostics, forever.
- **$99/year:** live RLS testing against your own semantic models, plus updates.
- One license covers a developer's machines and CI. **[Buy →](https://buy.polar.sh/polar_cl_5wclgy0ITjhod5qBsFC0rx9R8Kx3ENdKcfn3d28tY62)**

A commercial license governs use — see `LICENSE`.

## Support

Questions, a model shape that doesn't fit, or a false positive? Reach us through
your Polar customer portal (linked on your receipt). Built by **Green Analytics Ltd**.

## Roadmap

- [ ] XMLA/ADOMD connector (activate roles by name; unattended CI at scale)
- [ ] `sempy_labs` notebook connector (Direct Lake-native impersonation)
- [ ] HTML report; GitHub Action / Azure DevOps task wrapper
- [ ] Excel "source of truth" reconciliation
