feat: scaffold encryption capability boundaries
This commit is contained in:
35
.gitea/ISSUE_TEMPLATE/bug_report.md
Normal file
35
.gitea/ISSUE_TEMPLATE/bug_report.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
name: "Bug"
|
||||||
|
about: "Report a reproducible defect, regression, or incorrect behavior"
|
||||||
|
title: "[Bug] "
|
||||||
|
labels:
|
||||||
|
- type/bug
|
||||||
|
- status/triage
|
||||||
|
- module/encryption
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Repository:
|
||||||
|
- Area/module:
|
||||||
|
- Affected version or commit:
|
||||||
|
|
||||||
|
## Behavior
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
|
||||||
|
Actual:
|
||||||
|
|
||||||
|
## Reproduction
|
||||||
|
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
Logs, screenshots, traces, or failing test output:
|
||||||
|
|
||||||
|
## Verification Target
|
||||||
|
|
||||||
|
Command or workflow that should pass when fixed:
|
||||||
1
.gitea/ISSUE_TEMPLATE/config.yaml
Normal file
1
.gitea/ISSUE_TEMPLATE/config.yaml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
27
.gitea/ISSUE_TEMPLATE/docs_workflow.md
Normal file
27
.gitea/ISSUE_TEMPLATE/docs_workflow.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
name: "Docs / workflow"
|
||||||
|
about: "Request documentation, process, or developer workflow changes"
|
||||||
|
title: "[Docs] "
|
||||||
|
labels:
|
||||||
|
- type/docs
|
||||||
|
- status/triage
|
||||||
|
- module/encryption
|
||||||
|
- area/docs
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Repository:
|
||||||
|
- Document or workflow:
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
|
||||||
|
What is missing, unclear, duplicated, or stale?
|
||||||
|
|
||||||
|
## Desired State
|
||||||
|
|
||||||
|
What should the docs or workflow make clear?
|
||||||
|
|
||||||
|
## Verification Target
|
||||||
|
|
||||||
|
How should this be checked?
|
||||||
32
.gitea/ISSUE_TEMPLATE/feature_request.md
Normal file
32
.gitea/ISSUE_TEMPLATE/feature_request.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: "Feature"
|
||||||
|
about: "Propose new user-visible behavior or platform capability"
|
||||||
|
title: "[Feature] "
|
||||||
|
labels:
|
||||||
|
- type/feature
|
||||||
|
- status/triage
|
||||||
|
- module/encryption
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
What user, operator, or developer problem should this solve?
|
||||||
|
|
||||||
|
## Proposed Capability
|
||||||
|
|
||||||
|
What should exist when this is done?
|
||||||
|
|
||||||
|
## Ownership
|
||||||
|
|
||||||
|
- Owning repository:
|
||||||
|
- Related module repositories:
|
||||||
|
- Extension point or integration boundary:
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [ ]
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Verification Target
|
||||||
|
|
||||||
|
Command, scenario, or UI flow that should prove completion:
|
||||||
28
.gitea/ISSUE_TEMPLATE/task.md
Normal file
28
.gitea/ISSUE_TEMPLATE/task.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: "Task"
|
||||||
|
about: "Track implementation, maintenance, or migration work"
|
||||||
|
title: "[Task] "
|
||||||
|
labels:
|
||||||
|
- type/task
|
||||||
|
- status/triage
|
||||||
|
- module/encryption
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
What needs to be completed?
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- Owning repository:
|
||||||
|
- In-scope:
|
||||||
|
- Out-of-scope:
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
- [ ]
|
||||||
|
- [ ]
|
||||||
|
|
||||||
|
## Verification Target
|
||||||
|
|
||||||
|
Command or manual check:
|
||||||
25
.gitea/ISSUE_TEMPLATE/tech_debt.md
Normal file
25
.gitea/ISSUE_TEMPLATE/tech_debt.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
name: "Tech debt"
|
||||||
|
about: "Track cleanup, refactoring, risk reduction, or deferred engineering work"
|
||||||
|
title: "[Debt] "
|
||||||
|
labels:
|
||||||
|
- type/debt
|
||||||
|
- status/triage
|
||||||
|
- module/encryption
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current Cost
|
||||||
|
|
||||||
|
What does this make harder, riskier, slower, or more fragile?
|
||||||
|
|
||||||
|
## Desired Shape
|
||||||
|
|
||||||
|
What should the code, tests, or architecture look like afterwards?
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
What behavior, compatibility, or module boundary must be preserved?
|
||||||
|
|
||||||
|
## Verification Target
|
||||||
|
|
||||||
|
Focused checks that should pass:
|
||||||
15
.gitea/PULL_REQUEST_TEMPLATE.md
Normal file
15
.gitea/PULL_REQUEST_TEMPLATE.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
## Issue
|
||||||
|
|
||||||
|
Closes #
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Follow-up issues:
|
||||||
353
.gitignore
vendored
Normal file
353
.gitignore
vendored
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
# ---> Node
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# vitepress build output
|
||||||
|
**/.vitepress/dist
|
||||||
|
|
||||||
|
# vitepress cache directory
|
||||||
|
**/.vitepress/cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
# Local WebUI test/build scratch directories
|
||||||
|
.component-test-build/
|
||||||
|
.file-drop-test-build/
|
||||||
|
.module-test-build/
|
||||||
|
.policy-test-build/
|
||||||
|
.template-preview-test-build/
|
||||||
|
.import-test-build/
|
||||||
|
webui/.component-test-build/
|
||||||
|
webui/.file-drop-test-build/
|
||||||
|
webui/.module-test-build/
|
||||||
|
webui/.policy-test-build/
|
||||||
|
webui/.template-preview-test-build/
|
||||||
|
webui/.import-test-build/
|
||||||
|
|
||||||
|
# Security audit reports
|
||||||
|
audit-reports/
|
||||||
|
|
||||||
|
# ---> Python
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# UV
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
#uv.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||||
|
.pdm.toml
|
||||||
|
.pdm-python
|
||||||
|
.pdm-build/
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
# Ruff stuff:
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# PyPI configuration file
|
||||||
|
.pypirc
|
||||||
|
|
||||||
|
# ---> VisualStudioCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
*.db
|
||||||
|
|
||||||
|
# GovOPlaN local runtime state
|
||||||
|
runtime/
|
||||||
|
|
||||||
|
# GovOPlaN WebUI test output
|
||||||
|
webui/.module-test-build/
|
||||||
|
webui/.component-test-build/
|
||||||
21
AGENTS.md
Normal file
21
AGENTS.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# GovOPlaN Encryption Codex Guide
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This repository owns optional cryptographic platform capabilities: vaults, key
|
||||||
|
hierarchies, content-protection profiles, E2EE recipient and device keys,
|
||||||
|
rotation, recovery ceremonies, and disable/uninstall assurance.
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
- Core owns neutral capability contracts and module discovery.
|
||||||
|
- Feature modules own plaintext semantics, authorization, retention, and normal
|
||||||
|
resource ownership.
|
||||||
|
- This module may protect feature-owned payloads but must not become their
|
||||||
|
business-data store.
|
||||||
|
- Never add placeholder, home-grown, or unauthenticated cryptography.
|
||||||
|
- A disable or uninstall operation must prove that every protection reference
|
||||||
|
was decrypted, rewrapped, explicitly exported, or cryptographically deleted.
|
||||||
|
- Ownership recovery and cryptographic key recovery are separate processes.
|
||||||
|
|
||||||
|
Use Gitea issues as the canonical backlog and state log.
|
||||||
53
README.md
Normal file
53
README.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# GovOPlaN Encryption
|
||||||
|
|
||||||
|
<!-- govoplan-repository-type:start -->
|
||||||
|
**Repository type:** module (platform).
|
||||||
|
<!-- govoplan-repository-type:end -->
|
||||||
|
|
||||||
|
`govoplan-encryption` is the optional platform boundary for managed key vaults,
|
||||||
|
content encryption, end-to-end encryption profiles, key rotation, recovery, and
|
||||||
|
cryptographic deletion assurance.
|
||||||
|
|
||||||
|
The module is deliberately scaffolded before cryptographic implementation. It
|
||||||
|
announces stable integration surfaces and policy boundaries without presenting
|
||||||
|
placeholder cryptography as production-ready protection.
|
||||||
|
|
||||||
|
## Boundary
|
||||||
|
|
||||||
|
The module will own:
|
||||||
|
|
||||||
|
- vault and key hierarchy metadata
|
||||||
|
- envelope-key wrapping and rotation workflows
|
||||||
|
- content-protection profiles, including E2EE profiles
|
||||||
|
- device and recipient key registration
|
||||||
|
- recovery ceremonies, assurance evidence, and key custody
|
||||||
|
- disable and uninstall preflight for protected content
|
||||||
|
|
||||||
|
Feature modules continue to own their content, authorization, retention, and
|
||||||
|
normal ownership records. They integrate through optional encryption
|
||||||
|
capabilities and store only stable protection references and ciphertext.
|
||||||
|
|
||||||
|
## Disable Rule
|
||||||
|
|
||||||
|
Disabling or uninstalling this module must never make protected content silently
|
||||||
|
unreadable. Every protected object must first be decrypted, rewrapped to another
|
||||||
|
available provider, exported with explicit key custody, or deliberately
|
||||||
|
destroyed under an authorized cryptographic-deletion process. The eventual
|
||||||
|
uninstall guard will block while unresolved protection references remain.
|
||||||
|
|
||||||
|
See [docs/ENCRYPTION_BOUNDARY.md](docs/ENCRYPTION_BOUNDARY.md) for the initial
|
||||||
|
threat, ownership, recovery, and lifecycle decisions.
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
|
||||||
|
The repository currently contains a discoverable manifest, permission and role
|
||||||
|
metadata, versioned interface announcements, documentation, and focused tests.
|
||||||
|
It has no routes, persistence, WebUI, key generation, or encryption runtime yet.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/DATA/git/govoplan-encryption
|
||||||
|
PYTHONPATH=src:/mnt/DATA/git/govoplan-core/src \
|
||||||
|
/mnt/DATA/git/govoplan/.venv/bin/python -m unittest discover -s tests
|
||||||
|
```
|
||||||
50
docs/ENCRYPTION_BOUNDARY.md
Normal file
50
docs/ENCRYPTION_BOUNDARY.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Encryption Boundary
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
`govoplan-encryption` is an optional cryptographic service module. It supplies
|
||||||
|
key and content-protection capabilities to modules that choose to use them. It
|
||||||
|
does not own feature data, normal authorization, retention, or business
|
||||||
|
ownership.
|
||||||
|
|
||||||
|
## Initial Invariants
|
||||||
|
|
||||||
|
1. Resource ownership and cryptographic key custody are independent.
|
||||||
|
2. Administrative ownership recovery does not grant encryption keys.
|
||||||
|
3. Key recovery is a separate, high-assurance, auditable ceremony.
|
||||||
|
4. Every ciphertext carries a stable protection profile, key version, algorithm
|
||||||
|
suite, and authenticated context reference.
|
||||||
|
5. Rotation and rewrapping are resumable and idempotent.
|
||||||
|
6. Protected content cannot silently fall back to plaintext.
|
||||||
|
7. Provider loss, disabled modules, unavailable devices, and recovery delay are
|
||||||
|
visible states, not generic read failures.
|
||||||
|
8. Disabling or uninstalling is blocked while unresolved protected content
|
||||||
|
remains.
|
||||||
|
|
||||||
|
## Planned Capability Families
|
||||||
|
|
||||||
|
- **Key vault:** create and resolve key hierarchies without exposing raw key
|
||||||
|
material to feature modules.
|
||||||
|
- **Content protection:** authenticated envelope encryption and decryption for
|
||||||
|
authorized feature-owned payloads.
|
||||||
|
- **E2EE profiles:** recipient/device key envelopes where the server cannot
|
||||||
|
decrypt normal content.
|
||||||
|
- **Rotation:** rewrap keys and migrate algorithm suites with bounded progress
|
||||||
|
and evidence.
|
||||||
|
- **Recovery ceremony:** quorum, delay, recent authentication, custody evidence,
|
||||||
|
and explicit scope.
|
||||||
|
- **Disable preflight:** inventory protection references and produce a blocking
|
||||||
|
migration plan.
|
||||||
|
|
||||||
|
## Decisions Deferred Until Threat Modeling
|
||||||
|
|
||||||
|
- cryptographic libraries and external KMS/HSM providers
|
||||||
|
- server-managed versus client-managed profile suites
|
||||||
|
- per-object, per-vault, and per-recipient data-key granularity
|
||||||
|
- device enrollment and revocation protocol
|
||||||
|
- external-recipient key discovery and trust
|
||||||
|
- recovery quorum defaults for each assurance profile
|
||||||
|
- ciphertext portability and offline export format
|
||||||
|
|
||||||
|
These decisions require explicit threat models and interoperability fixtures.
|
||||||
|
They must not be inferred from ordinary resource-ownership workflows.
|
||||||
548
docs/gitea-labels.json
Normal file
548
docs/gitea-labels.json
Normal file
@@ -0,0 +1,548 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "type/bug",
|
||||||
|
"color": "d73a4a",
|
||||||
|
"description": "A reproducible defect, regression, or incorrect behavior.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "type/feature",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "New user-visible behavior or platform capability.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "type/user-story",
|
||||||
|
"color": "1d76db",
|
||||||
|
"description": "End-to-end user journey or real-world process story used to steer product slices.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "type/task",
|
||||||
|
"color": "1d76db",
|
||||||
|
"description": "Implementation, maintenance, migration, or operational work.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "type/debt",
|
||||||
|
"color": "fbca04",
|
||||||
|
"description": "Cleanup, refactoring, risk reduction, or deferred engineering work.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "type/docs",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "Documentation, process, or developer workflow work.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "priority/p0",
|
||||||
|
"color": "b60205",
|
||||||
|
"description": "Immediate stop-the-line priority.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "priority/p1",
|
||||||
|
"color": "d93f0b",
|
||||||
|
"description": "High priority for the next focused work window.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "priority/p2",
|
||||||
|
"color": "fbca04",
|
||||||
|
"description": "Normal planned priority.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "priority/p3",
|
||||||
|
"color": "c2e0c6",
|
||||||
|
"description": "Low priority or opportunistic cleanup.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status/triage",
|
||||||
|
"color": "d4c5f9",
|
||||||
|
"description": "Needs review, ownership, priority, or acceptance criteria.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status/ready",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "Ready for implementation.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status/in-progress",
|
||||||
|
"color": "0052cc",
|
||||||
|
"description": "Currently being worked.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status/blocked",
|
||||||
|
"color": "b60205",
|
||||||
|
"description": "Cannot progress without a decision, dependency, credential, or external change.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status/needs-info",
|
||||||
|
"color": "f9d0c4",
|
||||||
|
"description": "Needs clarifying input before implementation can proceed safely.",
|
||||||
|
"exclusive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/access",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "GovOPlaN access, identity, authentication, RBAC, and administration behavior.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/addresses",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "GovOPlaN Addresses module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/admin",
|
||||||
|
"color": "006b75",
|
||||||
|
"description": "GovOPlaN Admin module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/appointments",
|
||||||
|
"color": "d876e3",
|
||||||
|
"description": "GovOPlaN Appointments module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/audit",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "GovOPlaN Audit module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/calendar",
|
||||||
|
"color": "bfd4f2",
|
||||||
|
"description": "GovOPlaN Calendar module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/campaign",
|
||||||
|
"color": "d876e3",
|
||||||
|
"description": "GovOPlaN campaign module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/cases",
|
||||||
|
"color": "1d76db",
|
||||||
|
"description": "GovOPlaN Cases module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/connectors",
|
||||||
|
"color": "c2e0c6",
|
||||||
|
"description": "GovOPlaN Connectors module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/core",
|
||||||
|
"color": "0052cc",
|
||||||
|
"description": "GovOPlaN core runner, shared primitives, shell, or extension points.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/dashboard",
|
||||||
|
"color": "1d76db",
|
||||||
|
"description": "GovOPlaN Dashboard module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/dataflow",
|
||||||
|
"color": "1d76db",
|
||||||
|
"description": "GovOPlaN Dataflow module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/datasources",
|
||||||
|
"color": "006b75",
|
||||||
|
"description": "GovOPlaN governed datasource contracts, catalogs, and integrations.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/dms",
|
||||||
|
"color": "c5def5",
|
||||||
|
"description": "GovOPlaN Dms module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/docs",
|
||||||
|
"color": "c5def5",
|
||||||
|
"description": "GovOPlaN Docs module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/dist-lists",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "GovOPlaN Distribution Lists module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/erp",
|
||||||
|
"color": "fef2c0",
|
||||||
|
"description": "GovOPlaN Erp module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/evaluation",
|
||||||
|
"color": "bfdadc",
|
||||||
|
"description": "GovOPlaN Evaluation module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/files",
|
||||||
|
"color": "006b75",
|
||||||
|
"description": "GovOPlaN files module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/fit-connect",
|
||||||
|
"color": "fbca04",
|
||||||
|
"description": "GovOPlaN Fit Connect module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/forms",
|
||||||
|
"color": "f9d0c4",
|
||||||
|
"description": "GovOPlaN Forms module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/helpdesk",
|
||||||
|
"color": "c2e0c6",
|
||||||
|
"description": "GovOPlaN Helpdesk module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/identity-trust",
|
||||||
|
"color": "d4c5f9",
|
||||||
|
"description": "GovOPlaN Identity Trust module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/identity",
|
||||||
|
"color": "bfd4f2",
|
||||||
|
"description": "GovOPlaN Identity module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/idm",
|
||||||
|
"color": "0052cc",
|
||||||
|
"description": "GovOPlaN Idm module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/ledger",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "GovOPlaN Ledger module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/mail",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "GovOPlaN mail module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/notifications",
|
||||||
|
"color": "d876e3",
|
||||||
|
"description": "GovOPlaN Notifications module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/ops",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "GovOPlaN Ops module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/organizations",
|
||||||
|
"color": "bfdadc",
|
||||||
|
"description": "GovOPlaN Organizations module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/payments",
|
||||||
|
"color": "bfd4f2",
|
||||||
|
"description": "GovOPlaN Payments module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/permits",
|
||||||
|
"color": "fbca04",
|
||||||
|
"description": "GovOPlaN Permits module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/policy",
|
||||||
|
"color": "d93f0b",
|
||||||
|
"description": "GovOPlaN Policy module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/poll",
|
||||||
|
"color": "e4e669",
|
||||||
|
"description": "GovOPlaN Poll module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/portal",
|
||||||
|
"color": "1d76db",
|
||||||
|
"description": "GovOPlaN Portal module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/postbox",
|
||||||
|
"color": "d93f0b",
|
||||||
|
"description": "GovOPlaN Postbox module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/projects",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "GovOPlaN Projects module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/reporting",
|
||||||
|
"color": "c2e0c6",
|
||||||
|
"description": "GovOPlaN Reporting module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/risk-compliance",
|
||||||
|
"color": "b60205",
|
||||||
|
"description": "GovOPlaN Risk Compliance module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/search",
|
||||||
|
"color": "bfdadc",
|
||||||
|
"description": "GovOPlaN Search module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/scheduling",
|
||||||
|
"color": "d93f0b",
|
||||||
|
"description": "GovOPlaN Scheduling module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/tasks",
|
||||||
|
"color": "c5def5",
|
||||||
|
"description": "GovOPlaN Tasks module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/templates",
|
||||||
|
"color": "fef2c0",
|
||||||
|
"description": "GovOPlaN Templates module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/tenancy",
|
||||||
|
"color": "e4e669",
|
||||||
|
"description": "GovOPlaN Tenancy module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/tickets",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "GovOPlaN Tickets module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/views",
|
||||||
|
"color": "c5def5",
|
||||||
|
"description": "GovOPlaN governed task views, interface projections, and workflow view integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/wiki",
|
||||||
|
"color": "006b75",
|
||||||
|
"description": "GovOPlaN Wiki module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/workflow",
|
||||||
|
"color": "f9d0c4",
|
||||||
|
"description": "GovOPlaN Workflow module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/xoev",
|
||||||
|
"color": "d4c5f9",
|
||||||
|
"description": "GovOPlaN Xoev module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/xrechnung",
|
||||||
|
"color": "0052cc",
|
||||||
|
"description": "GovOPlaN Xrechnung module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "module/xta-osci",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "GovOPlaN Xta Osci module behavior or integration.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/auth",
|
||||||
|
"color": "bfd4f2",
|
||||||
|
"description": "Authentication, sessions, access bootstrap, or login behavior.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/tenancy",
|
||||||
|
"color": "bfdadc",
|
||||||
|
"description": "Tenant boundaries, provisioning, or tenant-scoped data behavior.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/rbac",
|
||||||
|
"color": "c5def5",
|
||||||
|
"description": "Permissions, roles, delegation, or authorization policy.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/governance",
|
||||||
|
"color": "fef2c0",
|
||||||
|
"description": "Governance policy, audit, privacy, retention, or compliance behavior.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/module-system",
|
||||||
|
"color": "bfe5bf",
|
||||||
|
"description": "Module discovery, manifests, capabilities, routing, or optional integrations.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/migrations",
|
||||||
|
"color": "e4e669",
|
||||||
|
"description": "Alembic migrations, schema bootstrap, or persistence evolution.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/webui",
|
||||||
|
"color": "1d76db",
|
||||||
|
"description": "Shared WebUI shell, frontend components, routing, or frontend tests.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/api",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "HTTP API contracts, routers, schemas, or API smoke behavior.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/db",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "Database sessions, models, transactions, or persistence primitives.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/devex",
|
||||||
|
"color": "bfd4f2",
|
||||||
|
"description": "Local developer workflow, scripts, tests, tooling, or release helpers.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/release",
|
||||||
|
"color": "c2e0c6",
|
||||||
|
"description": "Versioning, release locks, tags, packaging, or dependency pins.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/security",
|
||||||
|
"color": "b60205",
|
||||||
|
"description": "Security posture, static analysis, supply-chain hardening, or vulnerability remediation.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/docs",
|
||||||
|
"color": "5319e7",
|
||||||
|
"description": "Durable documentation and project guidance.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "area/marketing",
|
||||||
|
"color": "f9d0c4",
|
||||||
|
"description": "Public website, product messaging, publication copy, or legal page content.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source/todo-scan",
|
||||||
|
"color": "cccccc",
|
||||||
|
"description": "Imported from inline TODO/FIXME/HACK markers by the Gitea TODO importer.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source/backlog-import",
|
||||||
|
"color": "bfdadc",
|
||||||
|
"description": "Imported from markdown backlog, roadmap, plan, or TODO files.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source/security-audit",
|
||||||
|
"color": "d4c5f9",
|
||||||
|
"description": "Created from a structured security or code-quality audit report.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "audit/quick-fix",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "Audit finding that appears narrow and directly fixable.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "audit/structural",
|
||||||
|
"color": "d93f0b",
|
||||||
|
"description": "Audit finding that needs design, refactoring, or behavior review.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "audit/complexity",
|
||||||
|
"color": "fbca04",
|
||||||
|
"description": "Complexity finding from Radon, Xenon, or equivalent maintainability scans.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "audit/duplication",
|
||||||
|
"color": "c2e0c6",
|
||||||
|
"description": "Duplicated-code finding from jscpd or equivalent similarity scans.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "audit/false-positive",
|
||||||
|
"color": "cccccc",
|
||||||
|
"description": "Audit finding reviewed as a narrow false positive or acceptable risk.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "audit/needs-design",
|
||||||
|
"color": "f9d0c4",
|
||||||
|
"description": "Audit finding that needs an architectural or product decision before implementation.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "codex/ready",
|
||||||
|
"color": "0e8a16",
|
||||||
|
"description": "Suitable for Codex to pick up with the existing issue context.",
|
||||||
|
"exclusive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "codex/needs-human",
|
||||||
|
"color": "f9d0c4",
|
||||||
|
"description": "Needs an explicit human decision before Codex should implement.",
|
||||||
|
"exclusive": false
|
||||||
|
}
|
||||||
|
]
|
||||||
8
package.json
Normal file
8
package.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "@govoplan/encryption",
|
||||||
|
"version": "0.1.14",
|
||||||
|
"private": true,
|
||||||
|
"description": "GovOPlaN encryption platform module scaffold.",
|
||||||
|
"type": "module",
|
||||||
|
"peerDependencies": {}
|
||||||
|
}
|
||||||
22
pyproject.toml
Normal file
22
pyproject.toml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=69", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "govoplan-encryption"
|
||||||
|
version = "0.1.14"
|
||||||
|
description = "Optional key-vault and content-protection capabilities for GovOPlaN."
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
license = "AGPL-3.0-or-later"
|
||||||
|
authors = [{ name = "GovOPlaN" }]
|
||||||
|
dependencies = ["govoplan-core>=0.1.14"]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["src"]
|
||||||
|
|
||||||
|
[tool.setuptools.package-data]
|
||||||
|
govoplan_encryption = ["py.typed"]
|
||||||
|
|
||||||
|
[project.entry-points."govoplan.modules"]
|
||||||
|
encryption = "govoplan_encryption.backend.manifest:get_manifest"
|
||||||
5
src/govoplan_encryption/__init__.py
Normal file
5
src/govoplan_encryption/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
"""GovOPlaN encryption platform module."""
|
||||||
|
|
||||||
|
from govoplan_encryption.backend.manifest import get_manifest
|
||||||
|
|
||||||
|
__all__ = ["get_manifest"]
|
||||||
1
src/govoplan_encryption/backend/__init__.py
Normal file
1
src/govoplan_encryption/backend/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"""Backend integration surface for govoplan-encryption."""
|
||||||
142
src/govoplan_encryption/backend/manifest.py
Normal file
142
src/govoplan_encryption/backend/manifest.py
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from govoplan_core.core.modules import (
|
||||||
|
DocumentationTopic,
|
||||||
|
ModuleInterfaceProvider,
|
||||||
|
ModuleManifest,
|
||||||
|
PermissionDefinition,
|
||||||
|
RoleTemplate,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_ID = "encryption"
|
||||||
|
MODULE_NAME = "Encryption"
|
||||||
|
MODULE_VERSION = "0.1.14"
|
||||||
|
|
||||||
|
USE_SCOPE = "encryption:vault:use"
|
||||||
|
ADMIN_SCOPE = "encryption:vault:admin"
|
||||||
|
RECOVERY_SCOPE = "encryption:recovery:approve"
|
||||||
|
|
||||||
|
OPTIONAL_DEPENDENCIES = (
|
||||||
|
"access",
|
||||||
|
"audit",
|
||||||
|
"policy",
|
||||||
|
"notifications",
|
||||||
|
"files",
|
||||||
|
"postbox",
|
||||||
|
"campaigns",
|
||||||
|
"workflow",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _permission(
|
||||||
|
scope: str,
|
||||||
|
label: str,
|
||||||
|
description: str,
|
||||||
|
) -> PermissionDefinition:
|
||||||
|
module_id, resource, action = scope.split(":", 2)
|
||||||
|
return PermissionDefinition(
|
||||||
|
scope=scope,
|
||||||
|
label=label,
|
||||||
|
description=description,
|
||||||
|
category="Encryption",
|
||||||
|
level="tenant",
|
||||||
|
module_id=module_id,
|
||||||
|
resource=resource,
|
||||||
|
action=action,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSIONS = (
|
||||||
|
_permission(
|
||||||
|
USE_SCOPE,
|
||||||
|
"Use encryption profiles",
|
||||||
|
"Protect and decrypt authorized content through an available profile.",
|
||||||
|
),
|
||||||
|
_permission(
|
||||||
|
ADMIN_SCOPE,
|
||||||
|
"Administer encryption",
|
||||||
|
"Manage vaults, protection profiles, key rotation, and provider policy.",
|
||||||
|
),
|
||||||
|
_permission(
|
||||||
|
RECOVERY_SCOPE,
|
||||||
|
"Approve key recovery",
|
||||||
|
"Participate in an auditable recovery ceremony without gaining content ownership.",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ROLE_TEMPLATES = (
|
||||||
|
RoleTemplate(
|
||||||
|
slug="encryption_user",
|
||||||
|
name="Encryption user",
|
||||||
|
description="Use configured content-protection profiles.",
|
||||||
|
permissions=(USE_SCOPE,),
|
||||||
|
),
|
||||||
|
RoleTemplate(
|
||||||
|
slug="encryption_custodian",
|
||||||
|
name="Encryption custodian",
|
||||||
|
description="Administer encryption and participate in key recovery.",
|
||||||
|
permissions=(USE_SCOPE, ADMIN_SCOPE, RECOVERY_SCOPE),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
manifest = ModuleManifest(
|
||||||
|
id=MODULE_ID,
|
||||||
|
name=MODULE_NAME,
|
||||||
|
version=MODULE_VERSION,
|
||||||
|
optional_dependencies=OPTIONAL_DEPENDENCIES,
|
||||||
|
provides_interfaces=(
|
||||||
|
ModuleInterfaceProvider(name="encryption.key_vault", version="1.0.0"),
|
||||||
|
ModuleInterfaceProvider(
|
||||||
|
name="encryption.content_protection",
|
||||||
|
version="1.0.0",
|
||||||
|
),
|
||||||
|
ModuleInterfaceProvider(
|
||||||
|
name="encryption.recovery_ceremony",
|
||||||
|
version="1.0.0",
|
||||||
|
),
|
||||||
|
ModuleInterfaceProvider(
|
||||||
|
name="encryption.disable_preflight",
|
||||||
|
version="1.0.0",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
permissions=PERMISSIONS,
|
||||||
|
role_templates=ROLE_TEMPLATES,
|
||||||
|
documentation=(
|
||||||
|
DocumentationTopic(
|
||||||
|
id="encryption.boundary",
|
||||||
|
title="Encryption and key-custody boundary",
|
||||||
|
summary=(
|
||||||
|
"Optional vault, content-protection, rotation, recovery, and "
|
||||||
|
"disable-assurance capabilities."
|
||||||
|
),
|
||||||
|
body=(
|
||||||
|
"Encryption protects feature-owned content without taking over "
|
||||||
|
"its business ownership. Resource ownership recovery never "
|
||||||
|
"implicitly grants cryptographic keys. Disabling the module is "
|
||||||
|
"blocked until protected objects are decrypted, rewrapped, "
|
||||||
|
"explicitly exported, or cryptographically deleted."
|
||||||
|
),
|
||||||
|
layer="available",
|
||||||
|
documentation_types=("admin",),
|
||||||
|
audience=("administrator", "security_officer", "product_owner"),
|
||||||
|
related_modules=OPTIONAL_DEPENDENCIES,
|
||||||
|
order=100,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_manifest() -> ModuleManifest:
|
||||||
|
return manifest
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ADMIN_SCOPE",
|
||||||
|
"MODULE_ID",
|
||||||
|
"MODULE_VERSION",
|
||||||
|
"RECOVERY_SCOPE",
|
||||||
|
"USE_SCOPE",
|
||||||
|
"get_manifest",
|
||||||
|
"manifest",
|
||||||
|
]
|
||||||
1
src/govoplan_encryption/py.typed
Normal file
1
src/govoplan_encryption/py.typed
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
39
tests/test_manifest.py
Normal file
39
tests/test_manifest.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from govoplan_encryption.backend.manifest import (
|
||||||
|
ADMIN_SCOPE,
|
||||||
|
RECOVERY_SCOPE,
|
||||||
|
USE_SCOPE,
|
||||||
|
get_manifest,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EncryptionManifestTests(unittest.TestCase):
|
||||||
|
def test_manifest_is_an_optional_contract_only_seed(self) -> None:
|
||||||
|
manifest = get_manifest()
|
||||||
|
|
||||||
|
self.assertEqual(manifest.id, "encryption")
|
||||||
|
self.assertEqual(manifest.dependencies, ())
|
||||||
|
self.assertIn("access", manifest.optional_dependencies)
|
||||||
|
self.assertEqual(
|
||||||
|
{permission.scope for permission in manifest.permissions},
|
||||||
|
{USE_SCOPE, ADMIN_SCOPE, RECOVERY_SCOPE},
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
{provider.name for provider in manifest.provides_interfaces},
|
||||||
|
{
|
||||||
|
"encryption.key_vault",
|
||||||
|
"encryption.content_protection",
|
||||||
|
"encryption.recovery_ceremony",
|
||||||
|
"encryption.disable_preflight",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertIsNone(manifest.route_factory)
|
||||||
|
self.assertIsNone(manifest.migration_spec)
|
||||||
|
self.assertIsNone(manifest.frontend)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user