Metadata-Version: 2.4
Name: scalio-catalog
Version: 0.1.0
Summary: Scalio Blueprint governance catalog (scalio.catalog/v2): check, effective desired state, drift, signed packs
License: Proprietary
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: cryptography>=42
Requires-Dist: jsonschema>=4.20
Requires-Dist: pyyaml>=6
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"

# scalio-catalog

Shared code for the Scalio Blueprint governance catalog: one desired state per tenant, used by Foundry (roll
out), Citadel (keep, drift) and Rosetta (document). Concept and decisions BP1-BP12:
https://claude.ai/artifact/8PYfvHPm17KsooerLU95Ar (scalio-docs `concepts/governance-catalog.md`, ADR 0027).
Format contract: scalio-docs `interfaces/catalog-format.md`.

Nothing in this package is secret. The catalog content lives in the private repo `scalio_blueprint`; the signing
seed stays in 1Password.

## Documents

| Kind | What | Owner |
| --- | --- | --- |
| `ResourceType` | Something in a tenant (name as in Microsoft365DSC/UTCM, e.g. `AADConditionalAccessPolicy`): properties, read/write endpoint, permission | Scalio |
| `Control` | One security statement: match, desired values, parameters, severity, texts DE/EN, frameworks | Scalio, MSP, customer |
| `Baseline` | Versioned bundle of controls with default values | Scalio, MSP |
| `Assignment` | Tenant -> baseline@version, mode, channel, values, exceptions, own controls | customer |
| `Pack` | Header of a signed package | Scalio, MSP |

References: `id` (highest), `id@1.2.3` (exact), `id@^1.2` (same major, at least 1.2). Assignments name an exact
version.

## Use in an app

```python
from scalio_catalog import Catalog, compare, effective, plan_upgrade, summary, verify

catalog = verify(package_bytes, TRUSTED_CATALOG_KEYS)        # signed pack from Compass or the image
eff = effective(catalog, assignment)                         # baseline + customer layer, master untouched
results = compare(eff, {c.id: read_resource(c) for c in eff.controls})   # app reads the tenant
print(summary(results))                                      # {"counts": ..., "score": 92}
plan = plan_upgrade(catalog, assignment, "scalio.kmu-standard@1.5.0")    # three-way, conflicts listed
```

`compare` statuses: `ok`, `drift`, `missing`, `excepted` (all deviations covered by an active exception),
`not_read`, `removed` (customer removed it), `incomplete` (a value is missing).

Values (later wins): control default, baseline `parameters`, value on the baseline entry, assignment `values`,
assignment `controlValues.<control>`. Exceptions need a reason, end date and approver; expired ones count as
deviations again and are listed in `problems`; at most 366 days when `approvedAt` is given.

## Command line

```
scalio-catalog validate <folders...>          check structure, references, texts
scalio-catalog effective <assignment> <folders...> [--today 2026-11-01]
scalio-catalog pack <folder> -o dist          sign (CATALOG_SIGNING_KEY or --key-file), --base for other packs
scalio-catalog verify <file> --key <public>   check a package
scalio-catalog keygen                         new key: seed to 1Password, public key into the apps
scalio-catalog schema > catalog-v2.schema.json
```

## Editing in VS Code

Install the YAML extension (Red Hat) and add to the workspace settings of `scalio_blueprint`:

```json
{ "yaml.schemas": { "./schema/catalog-v2.schema.json": ["controls/**/*.yaml", "baselines/**/*.yaml",
  "resource-types/**/*.yaml", "pack.yaml"] } }
```

(`scalio-catalog schema > schema/catalog-v2.schema.json` writes the file.)

## Release

Bump `pyproject.toml` and `__version__`, CHANGELOG line, merge, then "Freigeben" in the Scalio Dev cockpit (or
Actions -> Publish with the version). Publishes to PyPI via trusted publishing (no token).
