Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
91387d9
Plan security hardening branches
dominikletica Jun 15, 2026
ca133e0
Refine security hardening branch plans
dominikletica Jun 15, 2026
c8de6bb
Document legacy security plugin reference
dominikletica Jun 15, 2026
5e02369
Add security PR readiness planning notes
dominikletica Jun 15, 2026
d32772a
Document accessible IconCaptcha quiz fallback
dominikletica Jun 15, 2026
1808a2c
Add security planning edge-case guardrails
dominikletica Jun 15, 2026
4fa2be7
Document security log projection question
dominikletica Jun 15, 2026
04adeaa
Document IP retention security limits
dominikletica Jun 15, 2026
c8d927f
Merge pull request #101 from aavion/feat-security-planning
dominikletica Jun 15, 2026
c4c7a9e
Add security policy defaults
dominikletica Jun 15, 2026
7ec6a22
Adjust captcha challenge TTL default
dominikletica Jun 15, 2026
94c77ba
Refine website global rate defaults
dominikletica Jun 15, 2026
3e84f72
Tighten scheduler and probe security defaults
dominikletica Jun 15, 2026
25fdf40
Define recovery login bypass policy
dominikletica Jun 15, 2026
ed589d8
Clarify captcha auto-success limits
dominikletica Jun 15, 2026
a47a1c9
Document security enforcement policy order
dominikletica Jun 15, 2026
3340d58
Document security configuration surfaces
dominikletica Jun 15, 2026
a279eba
Document security surface coverage gaps
dominikletica Jun 15, 2026
823a39f
Add admin ACL enforcement branch plan
dominikletica Jun 15, 2026
852c1e2
Detail admin ACL enforcement plan
dominikletica Jun 15, 2026
7288c74
Merge pull request #103 from aavion/feat-security-policy-docs
dominikletica Jun 15, 2026
510e578
Add GeoIP resolver foundation
dominikletica Jun 15, 2026
8378ab4
Add MaxMind GeoIP provider
dominikletica Jun 15, 2026
958f833
Add GeoIP database update foundation
dominikletica Jun 15, 2026
3343fc2
Prevent GeoIP license key logging
dominikletica Jun 15, 2026
496530b
Assert GeoIP operations keep license key private
dominikletica Jun 15, 2026
25b0b7f
Seed GeoIP defaults during setup
dominikletica Jun 15, 2026
c505dbf
Surface GeoIP status in statistics settings
dominikletica Jun 15, 2026
b72cee2
Simplify GeoIP status scope
dominikletica Jun 15, 2026
83c4532
Align settings API GeoIP redaction test
dominikletica Jun 15, 2026
56cbca0
Harden GeoIP archive extraction
dominikletica Jun 15, 2026
de19383
Harden GeoIP path portability
dominikletica Jun 15, 2026
3615548
Harden GeoIP TAR validation
dominikletica Jun 15, 2026
bbe125e
Address GeoIP review findings
dominikletica Jun 16, 2026
4afcaaa
Address GeoIP review follow-ups
dominikletica Jun 16, 2026
bbeec04
Reject unsupported GeoIP databases
dominikletica Jun 16, 2026
82b457f
Merge pull request #104 from aavion/feat-security-geoip-observability
dominikletica Jun 16, 2026
0fdc5e4
Prepare abuse foundation worklog
dominikletica Jun 16, 2026
41da720
Document abuse foundation log projection scope
dominikletica Jun 16, 2026
64ad1db
Add database log projection foundation
dominikletica Jun 16, 2026
784f104
Move admin log browsing to database projections
dominikletica Jun 16, 2026
050f2d4
Clarify trusted proxy scope for abuse foundation
dominikletica Jun 16, 2026
5cc51e3
Clarify visitor identity proxy header policy
dominikletica Jun 16, 2026
1c97e8e
Use forwarding entropy for visitor fallback IDs
dominikletica Jun 16, 2026
0e04bf6
Add passive abuse request inspection
dominikletica Jun 16, 2026
a07b246
Record passive abuse signals
dominikletica Jun 16, 2026
ec3aba9
Make probe path patterns configurable
dominikletica Jun 16, 2026
31dfd5c
Track probe path route warning follow-up
dominikletica Jun 16, 2026
404369c
Specify follow-up notice
dominikletica Jun 16, 2026
de528b9
Record session visitor mismatch signals
dominikletica Jun 16, 2026
c64a44a
Clarify security header handoff
dominikletica Jun 16, 2026
f282d89
Use clock for security signal retention
dominikletica Jun 16, 2026
0892c9f
Harden log projection readiness
dominikletica Jun 16, 2026
ac0ee3f
Record abuse foundation final verification
dominikletica Jun 16, 2026
c0d0594
Restore application log browsing source
dominikletica Jun 16, 2026
924fdc9
Split admin log browsing facade
dominikletica Jun 16, 2026
273a7be
Harden database log browsing filters
dominikletica Jun 16, 2026
06ece05
Clarify abuse identity and intent policies
dominikletica Jun 16, 2026
19e0d36
Update dependencies and support guidelines
dominikletica Jun 16, 2026
dde0488
Address log browsing review gaps
dominikletica Jun 16, 2026
317d820
Document retention-bound enforcement windows
dominikletica Jun 16, 2026
3b44ed3
Simplify security signal retention settings
dominikletica Jun 16, 2026
c1f7758
Harden log browsing retention and pagination
dominikletica Jun 16, 2026
d04c98b
Tighten abuse classification path handling
dominikletica Jun 16, 2026
d0b859c
Document abuse foundation review fixes
dominikletica Jun 16, 2026
af12036
Cover log settings navigation
dominikletica Jun 16, 2026
2da4427
Update abuse foundation verification notes
dominikletica Jun 16, 2026
41aa8e3
Harden abuse foundation review edges
dominikletica Jun 16, 2026
7e7d27c
Harden abuse foundation review findings
dominikletica Jun 16, 2026
272aab5
Gate access surface locale prefixes
dominikletica Jun 16, 2026
7c960a5
Harden log filters and request intents
dominikletica Jun 16, 2026
da4f3fd
Merge pull request #105 from aavion/feat-security-abuse-foundation
dominikletica Jun 16, 2026
1ddaea1
Add admin ACL feature matrix
dominikletica Jun 16, 2026
449c8ed
Gate settings through admin ACL features
dominikletica Jun 16, 2026
6dee2e6
Enforce admin ACL on package workflows
dominikletica Jun 16, 2026
434bf0f
Invalidate admin ACL group cache on group changes
dominikletica Jun 16, 2026
da67688
Document admin ACL enforcement slice
dominikletica Jun 16, 2026
5c31bae
Enforce admin ACL on user workflows
dominikletica Jun 16, 2026
30a103d
Enforce admin ACL on operational surfaces
dominikletica Jun 16, 2026
cfdd237
Document admin ACL enforcement decisions
dominikletica Jun 16, 2026
6aa1286
Update navigation ACL expectations
dominikletica Jun 16, 2026
0dbf5f3
Improve admin ACL reviewability
dominikletica Jun 16, 2026
9db0f3d
Record admin ACL audit follow-up
dominikletica Jun 16, 2026
35068b6
Fix delegated admin ACL bypasses
dominikletica Jun 16, 2026
cc5ffc8
Fix admin ACL review findings
dominikletica Jun 16, 2026
4b65ec0
Merge pull request #106 from aavion/feat-security-admin-acl-enforcement
dominikletica Jun 16, 2026
59ef450
Start rate enforcement branch
dominikletica Jun 16, 2026
349526b
Document rate enforcement policy catalogue
dominikletica Jun 17, 2026
3e3ff78
Add rate limit policy catalogue
dominikletica Jun 17, 2026
39695a5
Add rate limit mode setting
dominikletica Jun 17, 2026
8b11566
Add rate limit decision facade
dominikletica Jun 17, 2026
e1f6acc
Enforce rate limits on requests
dominikletica Jun 17, 2026
b6a53e2
Add rate limit reset hooks
dominikletica Jun 17, 2026
61a3762
Document rate enforcement implementation
dominikletica Jun 17, 2026
f5704d8
Harden rate limit scheduler policy
dominikletica Jun 17, 2026
c12869e
Scale suspicious probe profile windows
dominikletica Jun 17, 2026
706c822
Cover cron rate limit route rendering
dominikletica Jun 17, 2026
e8bafbc
Clarify scheduler rate limit policy
dominikletica Jun 17, 2026
222dbc6
Record custom error page follow-up
dominikletica Jun 17, 2026
6485929
Version bump -> 0.2.5
dominikletica Jun 17, 2026
e17395d
Translate rate limit profile labels
dominikletica Jun 17, 2026
2f91cee
Update importmap dependencies
dominikletica Jun 17, 2026
268a6bf
Fix rate enforcement review findings
dominikletica Jun 17, 2026
91cca74
Fix rate limiter auth-stage bypasses
dominikletica Jun 17, 2026
7468b1c
Harden rate limiter review edge cases
dominikletica Jun 17, 2026
ceef826
Fix rate limiter bypass review findings
dominikletica Jun 17, 2026
cb206a4
Tighten rate limiter review hardening
dominikletica Jun 17, 2026
840d511
Harden rate limit probe and profile edges
dominikletica Jun 17, 2026
47e8d9f
Document cache panic delivery direction
dominikletica Jun 17, 2026
e6c266b
Charge bearer CORS preflight attempts
dominikletica Jun 17, 2026
38e8c57
Charge read-only owner unsafe preflights
dominikletica Jun 17, 2026
126d19e
Close bearer preflight and scheduler gaps
dominikletica Jun 17, 2026
6aea1c2
Harden probe setup and auth-failure limits
dominikletica Jun 17, 2026
7f81f91
Codify review readiness rules
dominikletica Jun 17, 2026
7333fa7
Harden setup rate limits and error resolution
dominikletica Jun 17, 2026
d5f4261
Document rate limit and error renderer hardening
dominikletica Jun 17, 2026
15aa164
Harden credentialed preflight rate checks
dominikletica Jun 17, 2026
2452b47
Prevent partial rate limit bucket spends
dominikletica Jun 18, 2026
6db53a5
Document rate limit consume tradeoff
dominikletica Jun 18, 2026
3ece8ae
Centralize API effective method policy
dominikletica Jun 18, 2026
bd64934
Centralize path scope matching
dominikletica Jun 18, 2026
52b6019
Move rate limit bucket policy into descriptors
dominikletica Jun 18, 2026
4ba4bd6
Centralize localized request path resolution
dominikletica Jun 18, 2026
c294fef
Harden technical path rate scopes
dominikletica Jun 18, 2026
b60da96
Merge pull request #107 from aavion/feat-security-rate-enforcement
dominikletica Jun 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .manifest
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
# APP_CHANNEL defines the target branch inside the specified repository.

##> aavion/studio manifest ###
APP_VERSION=0.2.4
APP_DATE=2026-06-14
APP_VERSION=0.2.5
APP_DATE=2026-06-17
APP_NAME=Studio
APP_AUTHOR=Dominik Letica
APP_DESCRIPTION=Symfony 8.1 based content-management system for structured project websites.
Expand Down
18 changes: 17 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,21 @@
- Translation changes must keep matching source catalogue files and keys synchronized across all locale directories under `translations/languages/`; runtime `translations/messages.*.yaml` files are generated from those sources.
- Refactors before the first public `1.0.0` release may remove obsolete code instead of keeping compatibility shims, but callers, tests, docs, and class map entries must be updated immediately.
- If a requested narrow change exposes unrelated drift, fix it only when it blocks the task; otherwise record the follow-up in `dev/WORKLOG.md`.
- When addressing review findings, trace adjacent and analogous code paths that share the same policy, transition, or boundary, and apply or explicitly rule out the same fix there to avoid one-path-only hardening.

### Review Finding Fixes
- Before applying a fix for a review finding, trace the affected boundary from source to sink and inspect adjacent, related, and analogous code paths that share the same classifier, subscriber, guard, resolver, route family, subject selection, response behavior, storage boundary, or policy decision.
- Prefer fixing the narrowest central boundary that covers all affected paths. Apply a path-local fix only when evidence shows the issue is truly path-specific.
- Keep review fixes simple, modular, and minimally invasive. Do not broaden them into unrelated refactors, compatibility shims, or speculative redesigns.
- While tracing the affected boundary, actively look for additional unreported edge cases, including bypasses, abuse paths, privacy leaks, performance regressions, setup/pre-auth behavior, disabled-feature fallbacks, response redaction, and cache/storage failure behavior.
- Fix small in-scope adjacent issues directly when they share the same boundary and risk profile. Record larger or behavior-changing follow-ups in `dev/WORKLOG.md` instead of hiding them inside the review fix.
- Add or update regression coverage for the reported finding and any adjacent paths changed by the fix. When an analogous path is inspected and intentionally not changed, make that reasoning clear in the worklog, final notes, or PR response where useful.

### PR Readiness Audits
- Before marking a branch, pull request, or feature slice ready for review, run the PR-readiness checklist as a real audit pass over the branch diff and the affected runtime surfaces. Do not treat checklist items as passive boxes to tick.
- The audit must explicitly review security/privacy considerations; public entry points; authentication, authorization, sessions, secrets, browser storage, and response redaction; package/module boundaries; access levels; route/API/live endpoint scopes; naming and collision risks; setup/init/CI behavior; cross-platform behavior; disabled-feature fallbacks; process and environment handling; default seed coverage for implemented config keys; translations and user-facing copy; project-rule, architecture, naming, documentation, and performance drift; and captured follow-up tasks.
- Use evidence from code inspection, focused tests, render checks, linting, documentation diffs, class map/worklog updates, and seed/default coverage as appropriate for the changed surface. If a checklist item is not applicable, record why instead of silently skipping it.
- Fix small readiness issues directly when they are in scope and low risk. Record larger, behavior-changing, or separate-domain issues in `dev/WORKLOG.md` with a clear next action.
- PR notes must summarize the readiness audit outcome, including verification commands, skipped checks or proof gaps, documentation/worklog/classmap status, translation status, security/privacy considerations, and remaining follow-ups.

## Build and Verification Commands
- `bin/init` initializes the repository, refreshes dependencies and assets, locks referenced Symfony UX icons locally when possible, and is the preferred recovery path for broken or incomplete `vendor/` packages because it removes an existing `vendor/` tree before Composer runs.
Expand Down Expand Up @@ -183,6 +197,8 @@

## Review Mode
- In code review, lead with findings ordered by severity and include file and line references.
- Review-fix implementation must follow the Review Finding Fixes rules under Change Expectations before applying code changes.
- PR-readiness sign-off must follow the PR Readiness Audits rules under Change Expectations instead of only copying checklist items.
- Verify worklog, documentation, tests, class map, translations, screenshots, security notes, and PR checklist items when they are relevant to the reviewed change.
- Check drift between code and feature drafts in `dev/draft/`; update it only when asked to make changes, otherwise report the drift.
- Review translation coverage with `bin/lint <changed translation paths...>` when user-facing copy changed.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Studio

> **Version**: 0.2.4
> **Version**: 0.2.5
> **Status**: Active development
> **Updated**: 2026-06-14
> **Updated**: 2026-06-17
> **Owner**: Dominik Letica
> **Purpose:** A Symfony-based CMS foundation for structured, extensible project websites.
Expand Down
8 changes: 4 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# Security Policy

> **Status**: Active
> **Updated**: 2026-05-20
> **Updated**: 2026-06-16
> **Owner**: Dominik Letica
> **Purpose:** Support and reporting policy.

## Supported Versions

### main-Channel
Stable builds (`main`-branch or stable releases, where `main` always reflects the latest stable release) are supported at least until the next version is publicly available.
### stable-Channel
Stable builds (`stable-*`-branch or tagless releases) are supported at least until the next version is publicly available.
Please consider to keep your environment always up to date for security patches to apply.
If you're facing any problems, please feel free to [report](https://github.com/aavion/studio/issues) them to get assistance.
**Note:** Versions prior to the first major release are considered `dev` (see below).

| Version | Supported |
| ------- | ------------------ |
| < 1.0.0 | :x: (see `dev`) |
| < 1.0.0 | :x: |

### beta-Channel
Beta builds (`beta-*` branch or releases with `beta`-tag) receive limited support via GitHub Issues at least until the next version is publicly available.
Expand Down
18 changes: 18 additions & 0 deletions assets/styles/system/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,24 @@ html {
border-bottom: 0;
}

.system-acl-group-grid {
display: grid;
gap: 0.5rem;
min-width: min(100%, 22rem);
}

.system-acl-group-row {
align-items: center;
display: grid;
gap: 0.5rem;
grid-template-columns: minmax(10rem, 1fr) minmax(8rem, 12rem);
}

.system-acl-group-row code {
display: block;
margin-top: 0.125rem;
}

.system-markdown,
.system-rich-text {
@apply text-base leading-7;
Expand Down
52 changes: 26 additions & 26 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 62 additions & 1 deletion config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ services:
App\Core\Event\EventHookDescriptorProviderInterface:
tags:
- { name: 'system.event_hook_provider', priority: 0 }
App\Core\Geo\GeoIpProviderInterface:
tags:
- { name: 'system.geoip_provider', priority: 0 }
App\Backend\BackendViewProviderInterface:
tags:
- { name: 'system.backend_view_provider', priority: 0 }
Expand Down Expand Up @@ -71,6 +74,9 @@ services:
App\Security\AclGroupReferenceProviderInterface:
tags:
- { name: 'system.acl_group_reference_provider', priority: 0 }
App\Core\AdminAcl\AdminFeatureProviderInterface:
tags:
- { name: 'system.admin_feature_provider', priority: 0 }

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
Expand Down Expand Up @@ -106,6 +112,7 @@ services:
- '../src/**/*Scope.php'
- '../src/**/*Source.php'
- '../src/Debug/RouteRenderOptions.php'
- '../src/Core/Geo/GeoIp2MaxMindDatabaseReader.php'
- '../src/Core/Package/PackageSpec.php'
- '../src/**/*Spec.php'
- '../src/**/*Status.php'
Expand Down Expand Up @@ -172,6 +179,10 @@ services:
arguments:
$sessionFactory: '@session.factory'

App\Command\RenderRouteCommand:
arguments:
$environment: '%kernel.environment%'

App\Setup\SetupRedirectSubscriber:
arguments:
$projectDir: '%kernel.project_dir%'
Expand Down Expand Up @@ -211,6 +222,10 @@ services:
arguments:
$providers: !tagged_iterator { tag: system.backend_view_provider }

App\Core\AdminAcl\AdminFeatureRegistry:
arguments:
$providers: !tagged_iterator { tag: system.admin_feature_provider }

App\View\Injection\ViewInjectionRegistry:
arguments:
$staticProviders: !tagged_iterator { tag: system.static_view_injection_provider }
Expand Down Expand Up @@ -249,6 +264,20 @@ services:
arguments:
$providers: !tagged_iterator { tag: system.acl_group_reference_provider }

App\Security\RateLimit\RateLimitLimiterFactory:
arguments:
$cachePool: '@cache.rate_limiter'
$lockFactory: '@lock.factory'

App\Security\RateLimit\RateLimitRequestSubscriber:
arguments:
$environment: '%kernel.environment%'
$projectDir: '%kernel.project_dir%'

App\Security\RateLimit\RateLimitAuthenticationSubscriber:
arguments:
$environment: '%kernel.environment%'

App\Localization\TranslationLanguageCatalog:
arguments:
$projectDir: '%kernel.project_dir%'
Expand Down Expand Up @@ -372,7 +401,33 @@ services:
alias: App\Core\Log\AccessLogger

App\Core\Geo\GeoIpResolverInterface:
alias: App\Core\Geo\NullGeoIpResolver
alias: App\Core\Geo\GeoIpResolver

App\Core\Geo\GeoIpResolver:
arguments:
$providers: !tagged_iterator { tag: system.geoip_provider }
$fallbackProvider: '@App\Core\Geo\NullGeoIpProvider'

App\Core\Geo\MaxMindGeoIpDatabaseReaderFactoryInterface:
alias: App\Core\Geo\GeoIp2MaxMindDatabaseReaderFactory

App\Core\Geo\MaxMindGeoIpDownloadClientInterface:
alias: App\Core\Geo\HttpMaxMindGeoIpDownloadClient

App\Core\Geo\MaxMindGeoIpArchiveExtractorInterface:
alias: App\Core\Geo\MaxMindGeoIpArchiveExtractor

App\Core\Geo\HttpMaxMindGeoIpDownloadClient:
arguments:
$httpClient: null

App\Core\Geo\MaxMindGeoIpProvider:
arguments:
$projectDir: '%kernel.project_dir%'

App\Core\Geo\MaxMindGeoIpDatabaseUpdater:
arguments:
$projectDir: '%kernel.project_dir%'

App\Core\Log\OperationLoggerInterface:
alias: App\Core\Log\OperationLogger
Expand Down Expand Up @@ -407,6 +462,10 @@ services:
$cacheDir: '%kernel.project_dir%/var/cache'
$environment: '%kernel.environment%'

App\Security\Abuse\AbuseSubjectResolver:
arguments:
$secret: '%kernel.secret%'

App\Core\Security\SecretPayloadProtector:
arguments:
$secret: '%kernel.secret%'
Expand Down Expand Up @@ -511,6 +570,8 @@ services:

App\View\Http\HttpErrorRenderer:
arguments:
$projectDir: '%kernel.project_dir%'
$environment: '%kernel.environment%'
$debug: '%kernel.debug%'

App\View\Http\HttpErrorSubscriber:
Expand Down
Loading