stkit 17.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. stkit-17.0.0/.gitignore +33 -0
  2. stkit-17.0.0/CHANGELOG.md +253 -0
  3. stkit-17.0.0/LICENSE +21 -0
  4. stkit-17.0.0/PKG-INFO +135 -0
  5. stkit-17.0.0/README.md +88 -0
  6. stkit-17.0.0/SECURITY.md +24 -0
  7. stkit-17.0.0/examples/minimal/.env-sample +78 -0
  8. stkit-17.0.0/examples/minimal/.gitignore +8 -0
  9. stkit-17.0.0/examples/minimal/README.md +16 -0
  10. stkit-17.0.0/examples/minimal/minimal/__init__.py +1 -0
  11. stkit-17.0.0/examples/minimal/minimal/app.py +9 -0
  12. stkit-17.0.0/examples/minimal/minimal/migrations/364232ae77d5_add_note.py +37 -0
  13. stkit-17.0.0/examples/minimal/minimal/note/__init__.py +15 -0
  14. stkit-17.0.0/examples/minimal/minimal/note/models.py +40 -0
  15. stkit-17.0.0/examples/minimal/minimal/note/templates/note/index.html +186 -0
  16. stkit-17.0.0/examples/minimal/minimal/note/views.py +113 -0
  17. stkit-17.0.0/examples/minimal/minimal/settings.py +7 -0
  18. stkit-17.0.0/examples/minimal/minimal/templates/layout.html +3 -0
  19. stkit-17.0.0/examples/minimal/pyproject.toml +26 -0
  20. stkit-17.0.0/examples/minimal/tests/__init__.py +0 -0
  21. stkit-17.0.0/examples/minimal/tests/test_app.py +23 -0
  22. stkit-17.0.0/examples/minimal/uv.lock +2039 -0
  23. stkit-17.0.0/pyproject.toml +107 -0
  24. stkit-17.0.0/stk/__init__.py +19 -0
  25. stkit-17.0.0/stk/__main__.py +6 -0
  26. stkit-17.0.0/stk/agent_login.py +78 -0
  27. stkit-17.0.0/stk/app.py +323 -0
  28. stkit-17.0.0/stk/checks.py +634 -0
  29. stkit-17.0.0/stk/cli/__init__.py +49 -0
  30. stkit-17.0.0/stk/cli/agent.py +267 -0
  31. stkit-17.0.0/stk/cli/base.py +79 -0
  32. stkit-17.0.0/stk/cli/database.py +199 -0
  33. stkit-17.0.0/stk/cli/develop.py +63 -0
  34. stkit-17.0.0/stk/cli/doctor.py +262 -0
  35. stkit-17.0.0/stk/cli/main.py +101 -0
  36. stkit-17.0.0/stk/cli/reports.py +296 -0
  37. stkit-17.0.0/stk/cli/smoke.py +399 -0
  38. stkit-17.0.0/stk/cli/users.py +259 -0
  39. stkit-17.0.0/stk/cli/watch.py +68 -0
  40. stkit-17.0.0/stk/extensions.py +29 -0
  41. stkit-17.0.0/stk/migrations/__init__.py +130 -0
  42. stkit-17.0.0/stk/migrations/env.py +58 -0
  43. stkit-17.0.0/stk/migrations/script.py.mako +17 -0
  44. stkit-17.0.0/stk/migrations/versions/stk_0001_initial_schema.py +213 -0
  45. stkit-17.0.0/stk/portal/views.py +34 -0
  46. stkit-17.0.0/stk/public/__init__.py +0 -0
  47. stkit-17.0.0/stk/public/models.py +0 -0
  48. stkit-17.0.0/stk/public/views.py +344 -0
  49. stkit-17.0.0/stk/scaffold/__init__.py +1 -0
  50. stkit-17.0.0/stk/scaffold/app/CLAUDE.md +65 -0
  51. stkit-17.0.0/stk/scaffold/app/Dockerfile +41 -0
  52. stkit-17.0.0/stk/scaffold/app/README.md +16 -0
  53. stkit-17.0.0/stk/scaffold/app/__app__/__init__.py +1 -0
  54. stkit-17.0.0/stk/scaffold/app/__app__/app.py +8 -0
  55. stkit-17.0.0/stk/scaffold/app/__app__/settings.py +7 -0
  56. stkit-17.0.0/stk/scaffold/app/claude/skills/stk-api/SKILL.md +52 -0
  57. stkit-17.0.0/stk/scaffold/app/claude/skills/stk-blueprint/SKILL.md +48 -0
  58. stkit-17.0.0/stk/scaffold/app/claude/skills/stk-deploy/SKILL.md +61 -0
  59. stkit-17.0.0/stk/scaffold/app/claude/skills/stk-lessons/SKILL.md +58 -0
  60. stkit-17.0.0/stk/scaffold/app/claude/skills/stk-migrate/SKILL.md +96 -0
  61. stkit-17.0.0/stk/scaffold/app/docker-compose.yml +88 -0
  62. stkit-17.0.0/stk/scaffold/app/dockerignore +13 -0
  63. stkit-17.0.0/stk/scaffold/app/env-sample +78 -0
  64. stkit-17.0.0/stk/scaffold/app/gitignore +8 -0
  65. stkit-17.0.0/stk/scaffold/app/nginx/nginx.conf +46 -0
  66. stkit-17.0.0/stk/scaffold/app/nginx/stk.conf +36 -0
  67. stkit-17.0.0/stk/scaffold/app/postgres/init-db.sh +8 -0
  68. stkit-17.0.0/stk/scaffold/app/pyproject.toml +23 -0
  69. stkit-17.0.0/stk/scaffold/app/tests/__init__.py +0 -0
  70. stkit-17.0.0/stk/scaffold/app/tests/test_app.py +23 -0
  71. stkit-17.0.0/stk/scaffold/generator.py +209 -0
  72. stkit-17.0.0/stk/scaffold/templates.py +437 -0
  73. stkit-17.0.0/stk/security.py +145 -0
  74. stkit-17.0.0/stk/settings.py +147 -0
  75. stkit-17.0.0/stk/shell.py +284 -0
  76. stkit-17.0.0/stk/static/VERSIONS.txt +4 -0
  77. stkit-17.0.0/stk/static/css/app.css +229 -0
  78. stkit-17.0.0/stk/static/css/layout.css +330 -0
  79. stkit-17.0.0/stk/static/css/vuetify.min.css +6 -0
  80. stkit-17.0.0/stk/static/icons/fonts/tabler-icons.woff2 +0 -0
  81. stkit-17.0.0/stk/static/icons/tabler-icons.min.css +4 -0
  82. stkit-17.0.0/stk/static/img/auth-bg.webp +0 -0
  83. stkit-17.0.0/stk/static/img/favicon.ico +0 -0
  84. stkit-17.0.0/stk/static/img/stk.svg +1664 -0
  85. stkit-17.0.0/stk/static/js/axios.min.js +5 -0
  86. stkit-17.0.0/stk/static/js/components/NotificationDropdown.js +156 -0
  87. stkit-17.0.0/stk/static/js/components/ThemeSwitcher.js +68 -0
  88. stkit-17.0.0/stk/static/js/components/TransitionExpand.js +64 -0
  89. stkit-17.0.0/stk/static/js/components/VerticalNavGroup.js +119 -0
  90. stkit-17.0.0/stk/static/js/components/VerticalNavLink.js +36 -0
  91. stkit-17.0.0/stk/static/js/components/VerticalNavSectionTitle.js +21 -0
  92. stkit-17.0.0/stk/static/js/components/index.js +47 -0
  93. stkit-17.0.0/stk/static/js/config.js +150 -0
  94. stkit-17.0.0/stk/static/js/vue.min.js +13 -0
  95. stkit-17.0.0/stk/static/js/vuetify.min.js +3148 -0
  96. stkit-17.0.0/stk/static/robots.txt +1 -0
  97. stkit-17.0.0/stk/tasks/__init__.py +78 -0
  98. stkit-17.0.0/stk/templates/401.html +14 -0
  99. stkit-17.0.0/stk/templates/404.html +12 -0
  100. stkit-17.0.0/stk/templates/500.html +13 -0
  101. stkit-17.0.0/stk/templates/_brand.html +1 -0
  102. stkit-17.0.0/stk/templates/auth_layout.html +26 -0
  103. stkit-17.0.0/stk/templates/cms/activities.html +135 -0
  104. stkit-17.0.0/stk/templates/cms/roles.html +215 -0
  105. stkit-17.0.0/stk/templates/cms/users.html +312 -0
  106. stkit-17.0.0/stk/templates/dashboard.html +132 -0
  107. stkit-17.0.0/stk/templates/index.html +52 -0
  108. stkit-17.0.0/stk/templates/layout.html +328 -0
  109. stkit-17.0.0/stk/templates/login-layout.html +54 -0
  110. stkit-17.0.0/stk/templates/security/_macros.html +39 -0
  111. stkit-17.0.0/stk/templates/security/_messages.html +12 -0
  112. stkit-17.0.0/stk/templates/security/change_password.html +100 -0
  113. stkit-17.0.0/stk/templates/security/confirm_email.html +44 -0
  114. stkit-17.0.0/stk/templates/security/email/change_notice.html +4 -0
  115. stkit-17.0.0/stk/templates/security/email/change_notice.txt +5 -0
  116. stkit-17.0.0/stk/templates/security/email/confirmation_instructions.html +3 -0
  117. stkit-17.0.0/stk/templates/security/email/confirmation_instructions.txt +3 -0
  118. stkit-17.0.0/stk/templates/security/email/login_instructions.html +5 -0
  119. stkit-17.0.0/stk/templates/security/email/login_instructions.txt +5 -0
  120. stkit-17.0.0/stk/templates/security/email/reset_instructions.html +1 -0
  121. stkit-17.0.0/stk/templates/security/email/reset_instructions.txt +3 -0
  122. stkit-17.0.0/stk/templates/security/email/reset_notice.html +1 -0
  123. stkit-17.0.0/stk/templates/security/email/reset_notice.txt +1 -0
  124. stkit-17.0.0/stk/templates/security/email/welcome.html +7 -0
  125. stkit-17.0.0/stk/templates/security/email/welcome.txt +7 -0
  126. stkit-17.0.0/stk/templates/security/forgot_password.html +63 -0
  127. stkit-17.0.0/stk/templates/security/login_user.html +206 -0
  128. stkit-17.0.0/stk/templates/security/mf_recovery.html +67 -0
  129. stkit-17.0.0/stk/templates/security/mf_recovery_codes.html +119 -0
  130. stkit-17.0.0/stk/templates/security/register_user.html +263 -0
  131. stkit-17.0.0/stk/templates/security/reset_password.html +53 -0
  132. stkit-17.0.0/stk/templates/security/send_confirmation.html +48 -0
  133. stkit-17.0.0/stk/templates/security/send_login.html +39 -0
  134. stkit-17.0.0/stk/templates/security/two_factor_select.html +78 -0
  135. stkit-17.0.0/stk/templates/security/two_factor_setup.html +166 -0
  136. stkit-17.0.0/stk/templates/security/two_factor_verify_code.html +71 -0
  137. stkit-17.0.0/stk/templates/security/wan_register.html +179 -0
  138. stkit-17.0.0/stk/templates/security/wan_signin.html +123 -0
  139. stkit-17.0.0/stk/templates/security/wan_verify.html +109 -0
  140. stkit-17.0.0/stk/user/__init__.py +0 -0
  141. stkit-17.0.0/stk/user/forms.py +10 -0
  142. stkit-17.0.0/stk/user/models.py +308 -0
  143. stkit-17.0.0/stk/user/views.py +339 -0
  144. stkit-17.0.0/stk/utils/email.py +32 -0
  145. stkit-17.0.0/stk/utils/ratelimit.py +67 -0
  146. stkit-17.0.0/stk/websocket.py +133 -0
  147. stkit-17.0.0/tests/test_agent_operability.py +318 -0
  148. stkit-17.0.0/tests/test_branding.py +29 -0
  149. stkit-17.0.0/tests/test_builder_ux.py +114 -0
  150. stkit-17.0.0/tests/test_cli.py +63 -0
  151. stkit-17.0.0/tests/test_composition.py +122 -0
  152. stkit-17.0.0/tests/test_csrf_exempt.py +51 -0
  153. stkit-17.0.0/tests/test_error_handler.py +21 -0
  154. stkit-17.0.0/tests/test_migration_drift.py +50 -0
  155. stkit-17.0.0/tests/test_production_security.py +683 -0
  156. stkit-17.0.0/tests/test_scaffolder.py +352 -0
  157. stkit-17.0.0/tests/test_security_compatibility.py +122 -0
  158. stkit-17.0.0/tests/test_shell.py +87 -0
  159. stkit-17.0.0/tests/test_smoke_pages.py +92 -0
  160. stkit-17.0.0/tests/test_static_versioning.py +27 -0
@@ -0,0 +1,33 @@
1
+ *.pyc
2
+ .webassets-cache
3
+ .idea
4
+ celerybeat-schedule
5
+ env
6
+ .env
7
+ .env.backup*
8
+ local_settings.py
9
+ node_modules/
10
+ .DS_Store
11
+ .sass-cache
12
+ .vscode/
13
+ .cache/
14
+ .parcel-cache
15
+ stk.sqlite3
16
+ instance/
17
+
18
+
19
+ __pycache__/
20
+
21
+ # Claude Code
22
+ .claude/settings.local.json
23
+ *.skill
24
+ .quartenv
25
+
26
+ # Private planning docs and security reviews (never publish; checks.py fails if tracked)
27
+ security-review*
28
+ docs/plans/
29
+ docs/stk-report.html
30
+ docs/superpowers/
31
+
32
+ # Browser smoke artifacts
33
+ .stk/smoke/
@@ -0,0 +1,253 @@
1
+ # Changelog
2
+
3
+ ## v17.0.0 (unreleased)
4
+
5
+ stk becomes an installed, versioned package. An app is a separate, thin package that composes it and never edits a framework file, so upgrading stk is a version bump plus whatever its release note says.
6
+
7
+ ### Breaking
8
+
9
+ - An app is no longer a fork of stk. `stk init <name>` writes an app package: `myapp/app.py` builds `Stk(__name__, config=Config, extensions=[...])`, settings are `class Config(stk.Config)` in `myapp/settings.py`, and the app depends on `stkit>=17,<18`: stk is published on PyPI as `stkit`, still imported as `stk` and run as `stk`. Commands find the app from `[tool.stk] app` in the nearest `pyproject.toml`, or from `STK_APP`.
10
+ - `create_app(Config)` is replaced by `Stk(import_name, config=..., extensions=[...])`. Each extension is a package with `init_app(app)`; its `models` module is imported before it is called. `run.py` is gone: uvicorn serves the `[tool.stk] app` value (`myapp.app:app`).
11
+ - Templates and static files resolve app first, then each extension's, then stk's. Core templates are reachable as `stk/<name>`. `layout.html` gains `title` and `navigation` blocks.
12
+ - The sidebar is data: `stk/static/js/navigation.js` is removed. Extensions add pages with `app.navigation.append({...})`; they appear under Dashboard in extension order.
13
+ - stk's migrations ship inside the package (`stk/migrations/`) as one squashed revision, `stk_0001`, with the branch label `stk`. An app keeps its own lineage in `myapp/migrations/`, and each app revision depends on stk's head. `stk db upgrade` runs `upgrade heads`. `alembic.ini` and the `alembic/` directory are gone. A database created by stk 16 is not upgraded.
14
+ - `stk new <module>` writes an extension into the app package and adds it to the app's `extensions` list; it no longer patches `stk/app.py` or `navigation.js`.
15
+ - `stk run` serves through uvicorn with a 3 second graceful shutdown, so Ctrl+C no longer hangs on open tabs. Its options are `--host`, `--port`, and `--reload/--no-reload`.
16
+ - Importing stk needs no environment: missing `SECRET_KEY` or `SECURITY_PASSWORD_SALT` fails when the app is built. `.env` is read from the working directory. `Config.APP_DIR` and `Config.PROJECT_ROOT` are removed; the default SQLite database is `instance/stk.db` beside the app package.
17
+ - `Dockerfile`, `docker-compose.yml`, `nginx/`, `postgres/`, and `.env-sample` move into the app template that `stk init` writes. Nginx and Caddy pass `/static/` to the app instead of reading `stk/static` from disk. `deploy.sh` requires `REPO`, your app's repository. `.gitattributes` and the merge-based upgrade guide are removed.
18
+ - `checks.py` moves to `stk/checks.py` and runs against the app. Its docs checks run only inside the stk repository.
19
+
20
+ ### Also
21
+
22
+ - `stk db check` and `stk smoke` use a throwaway database of the configured dialect, so Postgres apps are checked on Postgres (the role needs CREATEDB). Autogenerate never offers to drop PostGIS's `spatial_ref_sys`. `stk.migrations.portable_tables()` returns the tables SQLite can build.
23
+ - Autogenerated revisions import what their column types need, and pass ruff without per-file exceptions.
24
+ - `stk doctor` reports the app it loaded and understands two lineages.
25
+
26
+ ### Upgrade considerations
27
+
28
+ There is nothing to upgrade from: 17.0.0 starts the new design. To move an app built on stk 16, start a fresh app with `stk init`, move each module into the app package with an `init_app`, move its settings into the app's `Config`, turn template and navigation edits into overrides and `app.navigation` entries, and replace its migration history with one fresh app revision. Paste-ready prompt for a coding agent:
29
+
30
+ ```text
31
+ Move this app off its stk 16 fork onto stk 17. Run `uvx --from stkit stk init <name>` next to it. For each module the app added under stk/: move it to <name>/<module>/, give its __init__.py an init_app(app) that registers its blueprint and appends its sidebar entries to app.navigation, and add it to `extensions` in <name>/app.py. Move app settings into <name>/settings.py (class Config(stk.Config)). Replace edited stk templates with files at the same path in <name>/templates/ that extend "stk/<name>" and override blocks. Delete the old migrations, then run `uv run stk db upgrade` and `uv run stk db revision -m "initial"`. Done when `uv run stk verify` and `uv run stk smoke` pass and no file under stk is edited.
32
+ ```
33
+
34
+ ## v16.4.1 (2026-10-25)
35
+
36
+ No migration required.
37
+
38
+ - Apps built on stk upgrade by merging stk release tags: see Deployment, "Upgrading an app built on stk". `.gitattributes` keeps an app's README, CHANGELOG, lockfile, and brand files on merge once `git config merge.ours.driver true` is set. An app copied without stk's history records its starting commit once with `git merge -s ours --allow-unrelated-histories <commit>`.
39
+ - `stk smoke` skips every WebSocket route, not only `/ws`, and any path listed in the new `STK_SMOKE_SKIP` app config value.
40
+ - The Vue brace check in `stk verify` ignores `<script>` bodies, where JS template literals are valid.
41
+
42
+ ## v16.4.0 (2026-10-25)
43
+
44
+ No migration required.
45
+
46
+ - New `stk-lessons` skill. When a failure the docs did not warn about costs an agent time, it logs one line in `.stk/lessons.md` and continues. On request, it triages the log: drops covered or one-off lessons, confirms the rest in code, and proposes each at the strongest home that holds (code default, `stk verify` check, `stk doctor` hint, docs line, skill step). Nothing applies without approval. Apps built on stk get framework lessons in generic terms to send upstream.
47
+
48
+ ## v16.3.0 (2026-10-25)
49
+
50
+ No migration required.
51
+
52
+ - Static JS and CSS in the layouts load through `url_for('static', ...)`, which adds a content hash (`?v=...`). The app, `nginx/stk.conf`, and the Caddy config from `deploy.sh` cache versioned files forever and revalidate the rest. Servers set up by an earlier `deploy.sh` cached every static file for a year: re-run it or apply the new `handle_path /static/*` block to the Caddyfile.
53
+ - `alembic.ini` no longer names a database, so `uv run alembic` targets the app's database like `stk db` does.
54
+ - `Base` sets `eager_defaults`, so `server_default` and SQL `onupdate` columns are readable after a flush instead of raising `MissingGreenlet`.
55
+ - `TestingConfig` in `stk/settings.py` pins the database, sessions, mail, OAuth, rate limits, breach check, and agent login. Subclass it in tests instead of `Config` so `.env` never reaches them.
56
+ - `stk verify` fails on `{` inside a Vue `${ }` interpolation, which blanks the page.
57
+
58
+ ## v16.2.1 (2026-10-23)
59
+
60
+ No migration required.
61
+
62
+ - `stk verify` fails on a migration whose `upgrade()` drops or renames a table or column, retypes a column, or adds a NOT NULL column without a `server_default`. Mark a deliberate step with a `# destructive: <reason>` comment inside `upgrade()`.
63
+ - `stk verify` fails when `CLAUDE.md` grows past 8KB or a skill past 4KB, so the agent index stays an index.
64
+
65
+ ## v16.2.0 (2026-10-23)
66
+
67
+ No migration required.
68
+
69
+ - The docs in `docs/src/content/docs/` are the single source for humans and agents. `.stk/context/` and the `stk-dev` skill are removed; their content moved into the Frontend, Models, JSON APIs, Background Work, Build Loop, and Deployment pages. `AGENTS.md` is now an index of those pages plus the rules that fail silently. Apps that referenced `.stk/context/*.md` should point at the docs pages instead.
70
+ - `stk inspect commands` reports every command and option, as text, `--json`, or `--markdown`. The docs CLI reference is generated from it.
71
+ - `stk verify` fails when the CLI reference is stale, when `stk/settings.py` reads an environment variable the Configuration page does not list, when `AGENTS.md` misses a docs page, or when docs, skills, or the README point at a file that does not exist.
72
+ - New docs pages: Configuration, CLI Reference, Renaming Your App, and WebSockets in Background Work. The docs site uses the stk logo.
73
+
74
+ ## v16.1.0 (2026-10-19)
75
+
76
+ No migration required. Existing databases keep their constraint names and show no drift.
77
+
78
+ - `APP_NAME`, `APP_TAGLINE` and `APP_DESCRIPTION` settings brand titles and auth pages. The logo lives in one partial, `stk/templates/_brand.html`. The placeholder Terms of Service and Privacy Policy line is removed from login and registration.
79
+ - `stk.security.csrf_exempt` lets a signed third-party webhook skip the CSRF token check. Host, API body and pagination checks still apply, and the view must authenticate the caller itself.
80
+ - `stk smoke` also visits every parameterless GET page, skipping auth flows, APIs and webhooks, and fails on uncaught page errors.
81
+ - Unhandled database errors return 500 and are logged instead of using the SQLAlchemy error code as the status.
82
+ - `stk db downgrade -1` accepts relative targets.
83
+ - `stk install` and `stk create` reject email addresses the login form would refuse.
84
+ - New constraints are named by a convention on `Base.metadata`, so SQLite batch migrations can add foreign keys.
85
+ - The navigation drawer starts closed on phones.
86
+ - `stk --version` reports the framework version when an app renames its package, and `setup.sh` runs without a terminal.
87
+
88
+ ## v16.0.0 (2026-10-06)
89
+
90
+ Requires quart-security 2.0.1. Run `uv run stk db upgrade` and `uv run stk protect-mfa` before upgrading an existing deployment. Preserve the MFA encryption keys.
91
+
92
+ - Require CSRF tokens for application mutations and send them from Axios.
93
+ - Use single-use OAuth state, PKCE, signed Google ID tokens, and verified GitHub email. Disable automatic email linking and enforce local MFA and account lockout.
94
+ - Rotate Redis session IDs on authentication changes and keep tracking records aligned with revoked sessions.
95
+ - Use atomic SQL authentication limits across workers. Apply migration `20261006_0002` before starting the app.
96
+ - Bound WebSocket connections, queues, messages, and lifetime. Require same-origin connections and explicit broadcast recipients. Remove automatic audit broadcasts.
97
+ - Enforce admin password policy and bound API pagination. Use Argon2id for new passwords; existing hashes still verify.
98
+ - Encrypt enrolled and pending MFA seeds. `stk protect-mfa` encrypts dormant accounts and supports key rotation.
99
+ - Disable public password registration by default. Set `SECURITY_REGISTERABLE=True` only when required.
100
+ - Require unique database and Redis secrets plus TLS certificates in Docker Compose. Keep data services and the app port private.
101
+ - Update vulnerable runtime packages and add PostgreSQL and Redis security checks to CI.
102
+
103
+ See `SECURITY.md` for deployment requirements and review limits.
104
+
105
+ ## v15.0.0 (2026-10-06)
106
+
107
+ Requires quart-security 2.0.0 and a database migration before startup.
108
+ Run `uv run stk db upgrade` to add the shared authentication-state table.
109
+ Existing login cookies are invalidated.
110
+
111
+ - Share database sessions between authentication and application routes.
112
+ - Revoke authentication state on logout, password resets, and single-session login.
113
+ - Preserve local HTTP cookie configuration and default to secure cookies.
114
+ - Pass application settings to password hashing in account commands.
115
+ - Add regression checks for startup, copied cookies, session revocation, and TOTP replay.
116
+
117
+ ## v14.1.0 (2026-07-25)
118
+
119
+ ### Added
120
+ - `stk doctor`: env, secrets, database, migration state, admin user, vendored
121
+ assets, agent-login exposure, browser, and REPL, each problem with the command
122
+ that fixes it. `--json` for tooling.
123
+ - `stk verify --watch`: re-runs only the checks a changed file can break (models
124
+ touch migration drift, templates do not) and prints the remedy under a failure.
125
+ - Every verify check now carries its remedy, in the text output and in the JSON.
126
+ - `stk new <name>` generates and applies the migration, then prints the URL of the
127
+ page it created. `--no-migrate` opts out.
128
+ - Docs: `build-loop.mdx` and `shell.mdx`, both example-first.
129
+
130
+ ### Changed
131
+ - Alembic failures report one line plus a next step instead of a traceback.
132
+ - CI actions bumped off Node 20 (checkout v7, setup-uv v9, upload-artifact v7).
133
+ - `alembic.ini` sets `path_separator`, silencing the deprecation warning.
134
+
135
+ ### Removed
136
+ - `stk migrate` and `stk migration-status`, pure aliases for `stk db upgrade` and
137
+ `stk db current`.
138
+
139
+ ## v14.0.0 (2026-07-25)
140
+
141
+ Bundles the unreleased 13.4.x work (hardened auth via quart-security 1.4.1) with a
142
+ new CLI, a frontend upgrade, and three gates that catch failures the old gate could
143
+ not see.
144
+
145
+ ### Added
146
+ - `stk` command as the single entry point: grouped `--help`, app factory baked in
147
+ (no `QUART_APP`), `python -m stk` and `uv run stk` both work. `quart <command>`
148
+ keeps working.
149
+ - `stk shell`: async REPL with the app, a live `db` session, every model, query
150
+ helpers, and top-level `await`. Uses ptpython (dev extra) for highlighting,
151
+ fuzzy completion, and fish-style suggestions; falls back to the stdlib console.
152
+ `stk shell -c "await count(User)"` for one-shot queries and scripts.
153
+ - `stk db check`: fails when models have drifted from migrations, measured by
154
+ running migrations onto a throwaway database. Part of `stk verify`, so CI enforces it.
155
+ - `stk smoke` now visits `/`, measures WCAG contrast on every button, chip, and
156
+ alert, and fails on text that is invisible against its background.
157
+ - `checks.py` asserts every route the report calls guarded actually rejects
158
+ anonymous access.
159
+ - `vendor.sh` refreshes pinned frontend assets; versions recorded in
160
+ `stk/static/VERSIONS.txt`.
161
+
162
+ ### Changed
163
+ - **Vuetify 3.7.8 to 4.1.6.** Material Design 2 type classes are gone; 67 usages
164
+ renamed to the MD3 names (`text-h5` to `text-headline-small`, and so on). Forks
165
+ with custom templates must do the same rename. Mapping table in
166
+ `.stk/context/frontend.md`.
167
+ - Vue 3.3.4 to 3.5.40, now the production build (was shipping the dev build).
168
+ Axios to 1.18.1. Tabler Icons 3.45.0 self-hosted instead of an unpinned CDN.
169
+ - `stk/commands.py` (918 lines) split into `stk/cli/`: `agent`, `database`,
170
+ `users`, `reports`, `smoke`, `base`.
171
+ - Route auth in `stk inspect routes` is read from the actual guard chain instead
172
+ of guessed from path prefixes.
173
+ - `stk verify` prints the tail of a failing check instead of a bare cross.
174
+
175
+ ### Fixed
176
+ - Seven security routes (`/change`, `/tf-setup`, `/wan-register`, and others) were
177
+ reported as public while actually requiring auth.
178
+ - `GET /mf-recovery` returned 500 to anonymous users: the template used
179
+ `mf_recovery_form` while quart-security passes `recovery_form`.
180
+ - Nav filtering mutated state inside a computed, which hung the dashboard under
181
+ Vue 3.5's production reactivity (the dev build only warned).
182
+ - Buttons rendered as anchors took the link colour, so a primary button on a
183
+ primary background was invisible. Vuetify 4 ships in CSS cascade layers, which
184
+ let unlayered app CSS win.
185
+ - Smoke output redacted the agent-login token by list position, leaking it when a
186
+ page was added.
187
+
188
+ ### Removed
189
+ - 5.1MB of unused Material Design Icons (referenced nowhere).
190
+ - `register_shellcontext`, replaced by `stk shell`.
191
+ - Empty `stk/core/` and app packages left over from a killed branch.
192
+
193
+ ## v11.3.0 (2025-12-02)
194
+
195
+ ### Added
196
+ - Lite mode: Zero-config startup with `uv sync && flask run` — no Redis required
197
+ - Full mode: Optional Redis + Celery via `uv sync --extra full`
198
+ - SQLAlchemy-based sessions as default (Redis sessions optional)
199
+ - AI-assisted development with AGENTS.md for Claude Code and Cursor
200
+
201
+ ### Changed
202
+ - Redis and Celery moved to optional dependencies
203
+ - SQLite database path now uses absolute path in `instance/stk.db`
204
+ - Updated documentation for lite/full mode workflow
205
+ - Simplified README with clearer positioning
206
+
207
+ ## v11.2.0 (2025-04-24)
208
+
209
+ ### Added
210
+ - Production-ready Docker configuration with multi-stage builds
211
+ - PostgreSQL service in Docker Compose setup
212
+ - Improved environment variable handling for Docker
213
+ - Support for user-specific Docker UID configuration
214
+ - Enhanced setup.sh script with Docker configuration option
215
+
216
+ ### Changed
217
+ - Optimized Dockerfile with multi-stage build for smaller, more secure images
218
+ - Fixed Redis connectivity by using correct environment variables
219
+ - Improved nginx configuration with proper retry settings
220
+ - Enhanced tmpfs configuration for better performance
221
+ - Added proper health checks for all Docker services
222
+
223
+ ## v11.1.0 (2025-03-30)
224
+
225
+ ### Added
226
+ - Migrated from pip/venv to uv for package management
227
+ - Faster installation and dependency resolution
228
+ - Better Python environment isolation
229
+
230
+ ### Changed
231
+ - Updated setup.sh script to use uv instead of venv
232
+ - Modified Dockerfile to use uv for package installation
233
+ - Updated documentation to reference uv
234
+
235
+ ## v11.0 (2023-03-27)
236
+
237
+ ### Added
238
+ - New activity model to track user actions like creating and editing users/roles
239
+ - Cursor Rules for improved code generation and assistance
240
+ - Comprehensive documentation for Cursor Rules approach
241
+
242
+ ### Changed
243
+ - Improved user and roles tables design in both frontend and backend
244
+ - Transitioned from OpenAI integration to Cursor Rules for code generation
245
+ - Enhanced admin user creation with better console output
246
+
247
+ ### Removed
248
+ - Removed flask-openai dependency and related code generation commands
249
+ - Removed OpenAI API key requirements
250
+
251
+ ### Fixed
252
+ - Various UI and UX improvements
253
+ - Code cleanup and bug fixes
stkit-17.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Nidal Alhariri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
stkit-17.0.0/PKG-INFO ADDED
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.5
2
+ Name: stkit
3
+ Version: 17.0.0
4
+ Summary: An async Quart framework optimized for AI-assisted development workflows
5
+ Author-email: Level09 <hello@level09.com>
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: aiosmtplib>=5.0.0
10
+ Requires-Dist: aiosqlite>=0.20.0
11
+ Requires-Dist: alembic>=1.16.0
12
+ Requires-Dist: authlib<2,>=1.9.1
13
+ Requires-Dist: bcrypt>=4.3.0
14
+ Requires-Dist: blinker>=1.9.0
15
+ Requires-Dist: click>=8.3.1
16
+ Requires-Dist: cryptography>=45.0.5
17
+ Requires-Dist: email-validator>=2.2.0
18
+ Requires-Dist: httpx2>=2.16.0
19
+ Requires-Dist: httpx>=0.27.0
20
+ Requires-Dist: jinja2>=3.1.6
21
+ Requires-Dist: joserfc<2,>=1.7.1
22
+ Requires-Dist: libpass>=1.9.0
23
+ Requires-Dist: orjson>=3.10.18
24
+ Requires-Dist: pillow>=13.0.0
25
+ Requires-Dist: psycopg2-binary>=2.9.10
26
+ Requires-Dist: python-dotenv>=1.1.1
27
+ Requires-Dist: qrcode>=8.2
28
+ Requires-Dist: quart-security<3,>=2.0.1
29
+ Requires-Dist: quart-session>=3.0.0
30
+ Requires-Dist: quart>=0.20.0
31
+ Requires-Dist: rich>=14.0.0
32
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.41
33
+ Requires-Dist: uvicorn>=0.40.0
34
+ Requires-Dist: webauthn>=2.6.0
35
+ Requires-Dist: wtforms>=3.2.1
36
+ Provides-Extra: asgi
37
+ Requires-Dist: hypercorn>=0.17.0; extra == 'asgi'
38
+ Provides-Extra: dev
39
+ Requires-Dist: playwright; extra == 'dev'
40
+ Requires-Dist: pre-commit; extra == 'dev'
41
+ Requires-Dist: ptpython>=3.0.30; extra == 'dev'
42
+ Requires-Dist: ruff; extra == 'dev'
43
+ Provides-Extra: full
44
+ Requires-Dist: asyncpg>=0.30.0; extra == 'full'
45
+ Requires-Dist: redis>=7.1.0; extra == 'full'
46
+ Description-Content-Type: text/markdown
47
+
48
+ <p align="center">
49
+ <picture>
50
+ <source media="(prefers-color-scheme: dark)" srcset="docs/src/assets/logo-dark.webp">
51
+ <img src="docs/src/assets/logo-light.webp" alt="stk" width="360">
52
+ </picture>
53
+ </p>
54
+
55
+ <h1 align="center">stk</h1>
56
+
57
+ <p align="center">
58
+ <strong>Async Python framework with batteries you actually need.</strong><br>
59
+ Auth, 2FA, WebAuthn, OAuth, WebSockets, admin dashboard, Vue 3 frontend. No build step, no third-party auth services. One codebase, you own everything.
60
+ STK makes SaaS apps legible, changeable, testable, and operable by agents.
61
+ </p>
62
+
63
+ <p align="center">
64
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
65
+ <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"></a>
66
+ <a href="https://docs.astral.sh/uv/"><img src="https://img.shields.io/badge/uv-package%20manager-blueviolet.svg" alt="uv"></a>
67
+ </p>
68
+
69
+ <p align="center">
70
+ <a href="https://docs.stk.dev">Docs</a> &middot;
71
+ <a href="https://docs.stk.dev/llms.txt">llms.txt</a> &middot;
72
+ <a href="https://github.com/level09/stk/wiki">Tutorials</a>
73
+ </p>
74
+
75
+ ---
76
+
77
+ ```bash
78
+ uvx --from stkit stk init myapp && cd myapp
79
+ uv run stk db upgrade # database via Alembic
80
+ uv run stk install # admin user
81
+ uv run stk run # localhost:5000
82
+ ```
83
+
84
+ Your app is its own package that composes stk, not a fork of it. Upgrading stk is a version bump.
85
+
86
+ ## Why stk
87
+
88
+ Most frameworks give you routing and leave the rest as homework. Auth alone eats weeks. Then you bolt on Clerk or Auth0, hand your users' credentials to a third party, and pay per-MAU for the privilege.
89
+
90
+ stk ships what actually matters:
91
+
92
+ **You own your auth.** Login, session management, TOTP 2FA (Google Authenticator, Authy, 1Password), WebAuthn passkeys (Touch ID, YubiKey), recovery codes, OAuth (Google, GitHub). Production code, not a tutorial. Your users' data stays on your server.
93
+
94
+ **Async all the way down.** Quart + async SQLAlchemy + aiosmtplib + native WebSockets. Not async bolted onto a sync framework. Real concurrency without threads, workers, or callback hell.
95
+
96
+ **No JS build step.** Vue 3 + Vuetify 4 loaded directly in the browser. No webpack, no vite, no node_modules, no npm. Delete your frontend toolchain. Still get a polished admin dashboard with data tables, dark mode, collapsible sidebar, 5000+ icons.
97
+
98
+ **SQLite by default.** Deploy anywhere. No managed database required. PostgreSQL when you need it, not when the framework demands it.
99
+
100
+ **No Celery, no Redis (unless you want them).** Background tasks run on asyncio. Session store works with cookies or Redis. Complexity is opt-in.
101
+
102
+ **Built to be operated by agents.** `stk inspect` reports routes, auth guards, models, and commands as JSON. `stk verify` and `stk smoke` are a real gate: lint, migration drift, and a real browser that fails on console errors and invisible text. The docs ship in the repo and the gate fails when they drift from the code.
103
+
104
+ > **Want payments?** [ReadyKit](https://readykit.dev) adds Stripe, multi-tenancy, and teams on top of stk.
105
+
106
+ ## What's included
107
+
108
+ - **Auth and security:** Argon2id passwords (12 char minimum), TOTP 2FA, passkeys as first or second factor, recovery codes, Google and GitHub OAuth with PKCE and verified emails, session tracking by IP and device, account lockout, per-IP rate limits shared across workers, CSRF on every mutation. Public sign-up is off by default.
109
+ - **Admin dashboard:** users, roles, and an activity audit log, with server-paginated tables and JSON APIs.
110
+ - **Real-time:** authenticated, origin-checked WebSockets that push to a named user and close when the session ends.
111
+ - **Frontend:** Vue 3 and Vuetify 4 with no build step, dark mode, collapsible sidebar, notifications, Tabler Icons.
112
+ - **Tooling:** one CLI, `stk`: run, shell, new, db, doctor, verify, smoke, inspect, report, and user management.
113
+ - **Deploy:** a one-command VPS script (Caddy, systemd, hardened OS) or Docker Compose with PostgreSQL, Redis, and Nginx.
114
+
115
+ ## Stack
116
+
117
+ | Layer | Tech |
118
+ |-------|------|
119
+ | Runtime | Python 3.11+, [uv](https://docs.astral.sh/uv/) |
120
+ | Web | [Quart](https://quart.palletsprojects.com/) (async Flask) |
121
+ | ORM | SQLAlchemy 2.0+ async |
122
+ | Database | SQLite (default), PostgreSQL (optional) |
123
+ | Migrations | Alembic |
124
+ | Auth | [quart-security](https://quart-security.readthedocs.io/) (2FA, WebAuthn, OAuth) |
125
+ | Frontend | Vue 3, Vuetify 4, Axios |
126
+ | Server | Uvicorn (ASGI) behind Caddy or Nginx |
127
+
128
+ ## Documentation
129
+
130
+ Everything else lives at [docs.stk.dev](https://docs.stk.dev), and in this repo at `docs/src/content/docs/`:
131
+ [quick start](https://docs.stk.dev/getting-started/), [build loop](https://docs.stk.dev/build-loop/), [models](https://docs.stk.dev/models/), [frontend](https://docs.stk.dev/frontend/), [authentication](https://docs.stk.dev/authentication/), [configuration](https://docs.stk.dev/configuration/), [CLI reference](https://docs.stk.dev/cli/), [deployment](https://docs.stk.dev/deployment/), and [working with agents](https://docs.stk.dev/ai-coding/). Upgrade notes are in `CHANGELOG.md`; the production security contract is `SECURITY.md`.
132
+
133
+ ## License
134
+
135
+ MIT
stkit-17.0.0/README.md ADDED
@@ -0,0 +1,88 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="docs/src/assets/logo-dark.webp">
4
+ <img src="docs/src/assets/logo-light.webp" alt="stk" width="360">
5
+ </picture>
6
+ </p>
7
+
8
+ <h1 align="center">stk</h1>
9
+
10
+ <p align="center">
11
+ <strong>Async Python framework with batteries you actually need.</strong><br>
12
+ Auth, 2FA, WebAuthn, OAuth, WebSockets, admin dashboard, Vue 3 frontend. No build step, no third-party auth services. One codebase, you own everything.
13
+ STK makes SaaS apps legible, changeable, testable, and operable by agents.
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
18
+ <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"></a>
19
+ <a href="https://docs.astral.sh/uv/"><img src="https://img.shields.io/badge/uv-package%20manager-blueviolet.svg" alt="uv"></a>
20
+ </p>
21
+
22
+ <p align="center">
23
+ <a href="https://docs.stk.dev">Docs</a> &middot;
24
+ <a href="https://docs.stk.dev/llms.txt">llms.txt</a> &middot;
25
+ <a href="https://github.com/level09/stk/wiki">Tutorials</a>
26
+ </p>
27
+
28
+ ---
29
+
30
+ ```bash
31
+ uvx --from stkit stk init myapp && cd myapp
32
+ uv run stk db upgrade # database via Alembic
33
+ uv run stk install # admin user
34
+ uv run stk run # localhost:5000
35
+ ```
36
+
37
+ Your app is its own package that composes stk, not a fork of it. Upgrading stk is a version bump.
38
+
39
+ ## Why stk
40
+
41
+ Most frameworks give you routing and leave the rest as homework. Auth alone eats weeks. Then you bolt on Clerk or Auth0, hand your users' credentials to a third party, and pay per-MAU for the privilege.
42
+
43
+ stk ships what actually matters:
44
+
45
+ **You own your auth.** Login, session management, TOTP 2FA (Google Authenticator, Authy, 1Password), WebAuthn passkeys (Touch ID, YubiKey), recovery codes, OAuth (Google, GitHub). Production code, not a tutorial. Your users' data stays on your server.
46
+
47
+ **Async all the way down.** Quart + async SQLAlchemy + aiosmtplib + native WebSockets. Not async bolted onto a sync framework. Real concurrency without threads, workers, or callback hell.
48
+
49
+ **No JS build step.** Vue 3 + Vuetify 4 loaded directly in the browser. No webpack, no vite, no node_modules, no npm. Delete your frontend toolchain. Still get a polished admin dashboard with data tables, dark mode, collapsible sidebar, 5000+ icons.
50
+
51
+ **SQLite by default.** Deploy anywhere. No managed database required. PostgreSQL when you need it, not when the framework demands it.
52
+
53
+ **No Celery, no Redis (unless you want them).** Background tasks run on asyncio. Session store works with cookies or Redis. Complexity is opt-in.
54
+
55
+ **Built to be operated by agents.** `stk inspect` reports routes, auth guards, models, and commands as JSON. `stk verify` and `stk smoke` are a real gate: lint, migration drift, and a real browser that fails on console errors and invisible text. The docs ship in the repo and the gate fails when they drift from the code.
56
+
57
+ > **Want payments?** [ReadyKit](https://readykit.dev) adds Stripe, multi-tenancy, and teams on top of stk.
58
+
59
+ ## What's included
60
+
61
+ - **Auth and security:** Argon2id passwords (12 char minimum), TOTP 2FA, passkeys as first or second factor, recovery codes, Google and GitHub OAuth with PKCE and verified emails, session tracking by IP and device, account lockout, per-IP rate limits shared across workers, CSRF on every mutation. Public sign-up is off by default.
62
+ - **Admin dashboard:** users, roles, and an activity audit log, with server-paginated tables and JSON APIs.
63
+ - **Real-time:** authenticated, origin-checked WebSockets that push to a named user and close when the session ends.
64
+ - **Frontend:** Vue 3 and Vuetify 4 with no build step, dark mode, collapsible sidebar, notifications, Tabler Icons.
65
+ - **Tooling:** one CLI, `stk`: run, shell, new, db, doctor, verify, smoke, inspect, report, and user management.
66
+ - **Deploy:** a one-command VPS script (Caddy, systemd, hardened OS) or Docker Compose with PostgreSQL, Redis, and Nginx.
67
+
68
+ ## Stack
69
+
70
+ | Layer | Tech |
71
+ |-------|------|
72
+ | Runtime | Python 3.11+, [uv](https://docs.astral.sh/uv/) |
73
+ | Web | [Quart](https://quart.palletsprojects.com/) (async Flask) |
74
+ | ORM | SQLAlchemy 2.0+ async |
75
+ | Database | SQLite (default), PostgreSQL (optional) |
76
+ | Migrations | Alembic |
77
+ | Auth | [quart-security](https://quart-security.readthedocs.io/) (2FA, WebAuthn, OAuth) |
78
+ | Frontend | Vue 3, Vuetify 4, Axios |
79
+ | Server | Uvicorn (ASGI) behind Caddy or Nginx |
80
+
81
+ ## Documentation
82
+
83
+ Everything else lives at [docs.stk.dev](https://docs.stk.dev), and in this repo at `docs/src/content/docs/`:
84
+ [quick start](https://docs.stk.dev/getting-started/), [build loop](https://docs.stk.dev/build-loop/), [models](https://docs.stk.dev/models/), [frontend](https://docs.stk.dev/frontend/), [authentication](https://docs.stk.dev/authentication/), [configuration](https://docs.stk.dev/configuration/), [CLI reference](https://docs.stk.dev/cli/), [deployment](https://docs.stk.dev/deployment/), and [working with agents](https://docs.stk.dev/ai-coding/). Upgrade notes are in `CHANGELOG.md`; the production security contract is `SECURITY.md`.
85
+
86
+ ## License
87
+
88
+ MIT
@@ -0,0 +1,24 @@
1
+ # Security and production deployment
2
+
3
+ Use the locked dependencies with `uv sync --frozen --extra full`. Apply `uv run stk db upgrade` and `uv run stk protect-mfa` before starting an existing deployment. Version 16 adds `rate_limit_window`; version 15 added `quart_security_state`. Both tables are required. Docker Compose runs the migrations before the app starts.
4
+
5
+ Use a unique generated `SECRET_KEY` and `SECURITY_PASSWORD_SALT`. Set `STK_ENV=production`, `QUART_DEBUG=0`, and `SESSION_COOKIE_SECURE=True`. Set `STK_PUBLIC_URL` to the HTTPS origin of the app. Set `SECURITY_WAN_RP_ID` to its DNS name and `SECURITY_WAN_EXPECTED_ORIGIN` to that HTTPS origin. The public URL restricts request hosts and fixes OAuth callback URLs. Trust proxy headers only from your proxy. The Compose app port is private and Uvicorn trusts the internal proxy network.
6
+
7
+ The production Compose stack requires `DB_ADMIN_PASSWORD`, `DB_PASSWORD`, `REDIS_PASSWORD`, `STK_HOST`, `TLS_CERTIFICATE`, and `TLS_PRIVATE_KEY`. Passwords must be unique and URL-safe because they appear in connection URLs. Certificate paths must be absolute, valid for the public host, and readable by the configured container UID. Renew certificates and reload Nginx before expiry. New PostgreSQL volumes use a separate non-superuser app role. Existing volumes need an operator privilege review because initialization scripts do not run again. Only ports 80 and 443 are published. Port 80 redirects to HTTPS. Keep container images patched and restrict access to the Docker host and network.
8
+
9
+ Public password registration is disabled by default. Enable it only for an app that needs public registration. OAuth providers remain opt-in. OAuth creates accounts only from verified provider identities; it does not attach a provider to an existing email. Existing users must use their current sign-in method. Review provider links created before version 16 because this update cannot establish how those links were originally authorized. Provider access tokens are no longer stored for login. Remove stored legacy provider tokens through your approved data maintenance process.
10
+
11
+ All POST, PUT, PATCH, and DELETE routes require the session CSRF token in a form or the `X-CSRFToken` header. The shared layout configures Axios. Custom API clients must fetch a rendered page and include its token. These APIs use session authentication. Do not disable CSRF for production. Webhooks from third parties that have no session can opt out per view with `stk.security.csrf_exempt` placed below the route decorator; an exempt view must authenticate the caller itself, for example by verifying an HMAC signature, and still gets the host, API body, and pagination checks.
12
+
13
+ Authentication limits use atomic fixed-minute SQL windows shared across workers. Defaults are 120 authentication requests and 10 authentication attempts per IP per minute, shared across auth endpoints. `STK_AUTH_REQUEST_LIMIT` and `STK_AUTH_ATTEMPT_LIMIT` are application config values. Fixed windows permit a burst at a boundary. An edge proxy should apply total connection and traffic limits. Limits rely on a trusted client IP; behind a proxy, configure forwarded-header trust explicitly. A proxy error must not make the whole site use one IP or accept client-supplied IP headers.
14
+
15
+ WebSocket defaults allow 5 connections per user and 1000 per worker, a queue of 32 messages, and 60 incoming messages per minute with a 64 KiB message limit. Sessions are checked before each outgoing message and every 5 seconds. Logout, account deactivation, expiry, and session revocation close the connection. These checks bound the revocation delay. `STK_WS_*` application config values can tune these limits. Connections must use the same origin, or an explicit `STK_WS_ALLOWED_ORIGINS` list. Broadcasts require a user ID. Audit entries are stored in the database and remain accessible through the admin API. In-memory delivery is local to one worker; use a separate authorized message transport if the app needs cross-worker delivery.
16
+
17
+ New passwords use Argon2id. Legacy hashes verify and upgrade on login. Password creation and reset routes check minimum length and the breach service. The authentication dependency permits a password if that external service is unavailable; monitoring should detect these failures. Admin password hashes are generated off the event loop. MFA, OAuth, Redis, and shared state controls have regression tests. CI also checks PostgreSQL migrations, real Redis session behavior, and runtime dependency advisories.
18
+
19
+ The 2026-10-06 review covers framework routes and local test fixtures. It is not a certification of a deployed application. Validate live OAuth provider settings, real authenticator/passkey enrollment, proxy behavior, certificate renewal, backup restoration, monitoring, and traffic capacity in your staging environment before production. A dependency scan only checks published advisories. See `security-review-2026-10-06.md` for the original findings and remediation evidence.
20
+
21
+
22
+ TOTP seeds and pending setup secrets are encrypted by quart-security 2.0.1. Legacy seeds remain readable and upgrade on login or authenticated requests. `uv run stk protect-mfa` encrypts all dormant seeds and rotates existing encrypted seeds to the current key. The command prints only a count and commits the data changes as one transaction. Run it in a maintenance window after taking a protected backup.
23
+
24
+ The default MFA encryption key is derived from `SECRET_KEY` for backward-compatible setup. Keep it stable. For independent key rotation, set `SECURITY_TOTP_ENCRYPTION_KEYS` to a comma-separated list of Fernet keys. The first key writes new data; all listed keys read existing data. Generate a key with `uv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"`. Protect keys separately from database backups. To move from the default to an independent keyring, include the old default key from `derive_totp_encryption_key(old_secret_key)` in the keyring until existing seeds have been rotated and pending setup states have expired. Retain keys needed for recovery of required backups. Do not change `SECRET_KEY` while using its derived MFA key unless you preserve the old MFA key. Invalid ciphertext or a wrong key fails closed.
@@ -0,0 +1,78 @@
1
+ # ============================================
2
+ # STK CONFIGURATION
3
+ # ============================================
4
+ # Lite mode: uv sync && uv run stk run (just works)
5
+ # Full mode: uv sync --extra full (Redis + asyncpg)
6
+ # ============================================
7
+
8
+ # === CORE (Required) ===
9
+ SECRET_KEY=
10
+ QUART_DEBUG=1
11
+ STK_ENV=development
12
+ SECURITY_REGISTERABLE=False
13
+ SECURITY_PASSWORD_SALT=
14
+
15
+ # === BRANDING ===
16
+ #APP_NAME=stk
17
+ #APP_TAGLINE=Secure. Scalable. Swift.
18
+ #APP_DESCRIPTION=
19
+
20
+ # === DATABASE ===
21
+ # SQLite used by default (instance/stk.db) - no config needed
22
+ # Schema changes are tracked with Alembic migrations
23
+ # PostgreSQL (uncomment for production)
24
+ #SQLALCHEMY_DATABASE_URI=postgresql+asyncpg://postgres:pass@localhost/dbname
25
+
26
+ # === FULL MODE - Redis + asyncpg (optional) ===
27
+ # Uncomment after: uv sync --extra full
28
+ #REDIS_URL=redis://localhost:6379/1
29
+
30
+ # === OAUTH (optional) ===
31
+ GOOGLE_AUTH_ENABLED=False
32
+ GOOGLE_OAUTH_CLIENT_ID=your_google_client_id
33
+ GOOGLE_OAUTH_CLIENT_SECRET=your_google_client_secret
34
+
35
+ GITHUB_AUTH_ENABLED=False
36
+ GITHUB_OAUTH_CLIENT_ID=your_github_client_id
37
+ GITHUB_OAUTH_CLIENT_SECRET=your_github_client_secret
38
+
39
+ # For local development only (remove in production)
40
+ OAUTHLIB_INSECURE_TRANSPORT=1
41
+
42
+ # === MAIL (optional) ===
43
+ MAIL_SERVER=smtp.sendgrid.net
44
+ MAIL_USERNAME=sendgrid
45
+ MAIL_PASSWORD=sendgrid_secure_password
46
+ SECURITY_EMAIL_SENDER=info@domain.com
47
+
48
+ # === SESSION & COOKIES ===
49
+ # Local HTTP only. Use True with HTTPS in production.
50
+ SESSION_COOKIE_SECURE=False
51
+ SESSION_COOKIE_HTTPONLY=True
52
+ SESSION_COOKIE_SAMESITE=Lax
53
+ # Set to True to logout other sessions on login (single session per user)
54
+ DISABLE_MULTIPLE_SESSIONS=False
55
+
56
+ # ============================================
57
+ # DOCKER CONFIGURATION (docker compose up)
58
+ # ============================================
59
+ #COMPOSE_PROJECT_NAME=minimal
60
+ #PYTHONUNBUFFERED=true
61
+ #DOCKER_UID=1000
62
+ #DB_ADMIN_PASSWORD=generate-a-separate-admin-secret
63
+ #DB_PASSWORD=generate-a-unique-secret
64
+ #REDIS_PASSWORD=generate-a-unique-secret
65
+ #SQLALCHEMY_DATABASE_URI=postgresql+asyncpg://stk:${DB_PASSWORD}@postgres/stk
66
+ #REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/1
67
+
68
+ # Required by the production Docker stack. Use readable certificate files.
69
+ #STK_HOST=app.example.com
70
+ #TLS_CERTIFICATE=/absolute/path/fullchain.pem
71
+ #TLS_PRIVATE_KEY=/absolute/path/key.pem
72
+ #STK_PUBLIC_URL=https://app.example.com
73
+ #SECURITY_WAN_RP_ID=app.example.com
74
+ #SECURITY_WAN_EXPECTED_ORIGIN=https://app.example.com
75
+
76
+ # Optional independent MFA encryption keyring, newest key first.
77
+ # Generate Fernet keys and retain old keys during rotation. See SECURITY.md.
78
+ #SECURITY_TOTP_ENCRYPTION_KEYS=new-fernet-key,old-fernet-key
@@ -0,0 +1,8 @@
1
+ .env
2
+ .env.backup*
3
+ instance/
4
+ __pycache__/
5
+ *.pyc
6
+ .venv/
7
+ .ruff_cache/
8
+ .stk/smoke/