DirectoryIndex index.php
Options -Indexes
RewriteEngine On

# MyronCMS owns cache policy explicitly. Disable inherited mod_expires rules so
# dynamic HTML cannot acquire a second Cache-Control value or Expires header
# after PHP has emitted the public page cache policy.
<IfModule mod_expires.c>
    ExpiresActive Off
</IfModule>

# Remove app-controlled implementation banners where mod_headers is available.
<IfModule mod_headers.c>
    Header always unset X-Powered-By
    SetEnvIf Request_URI "(^|/)assets/media/" MYRON_STATIC_MEDIA_ASSET=1
    Header onsuccess unset Cache-Control env=MYRON_STATIC_MEDIA_ASSET
    Header always unset Cache-Control env=MYRON_STATIC_MEDIA_ASSET
    Header set Cache-Control "public, max-age=31536000, immutable" env=MYRON_STATIC_MEDIA_ASSET
</IfModule>

# Preserve bearer credentials for hosted Apache/PHP rewrite deployments.
SetEnvIfNoCase Authorization "^(.*)$" HTTP_AUTHORIZATION=$1
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

# RTW1 hardening: never serve private project files directly from the web root.
# Route dotted private paths through PHP so hosted Apache returns a clean 404
# instead of a host-level 500 for missing hidden directories.
RewriteRule ^\.(?!well-known(?:/|$)) index.php [L,QSA]
RewriteRule (^|/)\.env(\..*)?$ - [F,L]
RewriteRule (^|/)\.git(?:/|$) - [F,L]
RewriteRule (^|/)(?:composer\.(?:json|lock)|package(?:-lock)?\.json|pnpm-lock\.yaml|yarn\.lock|README(?:\.[A-Za-z0-9]+)?|AGENTS\.md)$ - [F,L]
RewriteRule (^|/)(?:vendor|node_modules|packages|ops|dev-references|docs|\.amphion|\.github|app/tests|app/storage|app/system|app/modules|app/api)(?:/|$) - [F,L]

# Runtime assets are physically stored under app/assets, but public/admin URLs
# may mount them below the configured admin path such as /touch-myron/assets.
RewriteRule ^assets/(.*)$ app/assets/$1 [L,QSA]
RewriteRule ^[^/]+/assets/(.*)$ app/assets/$1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L,QSA]
