Skip to content

feat: support disabling directory listing in the httpd oidc image - #56

Merged
nathanklick merged 1 commit into
mainfrom
feat/httpd-oidc-directory-listing-toggle
Sep 21, 2026
Merged

nathanklick merged 1 commit into
mainfrom
feat/httpd-oidc-directory-listing-toggle

Conversation

@nathanklick

@nathanklick nathanklick commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #55.

What this changes

The <Directory> block guarding the document root hardcodes Options SymLinksIfOwnerMatch Indexes in all five vhost blocks across the three site templates, and AllowOverride None blocks any .htaccess override, so there is currently no way to turn mod_autoindex off. Combined with HTTPD_SITE_DIRECTORY_INDEX defaulting to disabled when unset, an otherwise unconfigured container answers a directory request with a full listing of its document root — for the gcsfuse use case, the entire object namespace of the mounted bucket.

This adds HTTPD_SITE_DIRECTORY_LISTING_ENABLED and derives the rendered Options list from it:

HTTPD_SITE_DIRECTORY_LISTING_ENABLED rendered Options
unset (default), or any other value SymLinksIfOwnerMatch Indexes
0 or false SymLinksIfOwnerMatch

The templates now substitute ${HTTPD_SITE_DIRECTORY_OPTIONS} the same way they already substitute ${HTTPD_SITE_DIRECTORY_INDEX}. That variable is an implementation detail derived in configure_virtual_hosts and always overwritten there; the boolean is the supported knob.

Why not the existing idioms

  • uncomment_config_element (as used for ServerName, OIDCRemoteUserClaim, OIDCXForwardedHeaders) does not fit. Those are directives that are either present or absent. Here the two variants are the same directive with different arguments, so uncommenting would leave two Options lines in one block.
  • A second Options -Indexes directive is not viable either. Apache rejects a context that mixes the bare and +/- forms, so it would force the existing directive to be rewritten in +/- form throughout, changing its merge semantics.

Backward compatibility

The toggle is opt-out — only an explicit false or 0 drops Indexes. Leaving the variable unset renders exactly what this image renders today, so the upgrade is a no-op for existing deployments and nothing that relies on listings loses them silently.

HTTPD_SITE_DIRECTORY_OPTIONS also gets a Dockerfile ENV default. An undefined config variable inside an Options directive is a hard parse error (Illegal option ${...}) rather than the warning DirectoryIndex produces for the same situation, so the default keeps the config parsable when Apache is invoked without the entrypoint having run — apache2ctl configtest over docker exec, for instance.

Verification

Against the published 0.4.1 image with these files overlaid, serving a document root containing index.html, somefile.txt and subdir/nested.txt (no index in subdir/):

case GET / GET /subdir/ GET /subdir/nested.txt
stock 0.4.1, no overlay 200, listing 200, listing 200
overlay, variable unset 200, listing 200, listing 200
overlay, =0 403 403 200
overlay, =false 403 403 200
overlay, =0 + HTTPD_SITE_DIRECTORY_INDEX=index.html 200, index.html 403 200

Stock and unset-overlay are identical. Disabling the listing suppresses enumeration without affecting retrieval of files by name, and mod_autoindex logs the suppression explicitly (AH01276: ... server-generated directory index forbidden by Options directive).

apache2ctl configtest reports Syntax OK for default-nossl, default-ssl and default-ssl-redirect under both rendered Options values. shellcheck on entrypoint-helper.sh reports nothing beyond the pre-existing SC1091 for the logger.sh source.

Follow-up

Once this ships, applications/apache-httpd-oidc in release-engineering-infrastructure needs a matching httpd.site.directoryListing value and an appVersion bump. The sites it serves (jrs-reports, perf-analytics, cross-ledger-files) all currently run with the chart default directoryIndex: "disabled", which is precisely the combination that produces a browsable listing.

@nathanklick
nathanklick requested review from a team as code owners September 21, 2026 19:51
The <Directory> block guarding the document root hardcodes
Options SymLinksIfOwnerMatch Indexes in all five vhost blocks across the
three site templates, and AllowOverride None blocks any .htaccess override,
so there was no way to turn mod_autoindex off. Combined with
HTTPD_SITE_DIRECTORY_INDEX defaulting to "disabled" when unset, an otherwise
unconfigured container answers a directory request with a full listing of its
document root -- for the gcsfuse use case, the entire object namespace of the
mounted bucket.

Add HTTPD_SITE_DIRECTORY_LISTING_ENABLED and derive the rendered Options list
from it, substituting ${HTTPD_SITE_DIRECTORY_OPTIONS} into the templates the
same way ${HTTPD_SITE_DIRECTORY_INDEX} already is. The uncomment_config_element
idiom used for ServerName and OIDCRemoteUserClaim does not fit, because the two
variants are the same directive with different arguments rather than a directive
that is present or absent, and appending a second Options directive is not an
option either: Apache rejects a context that mixes the bare and +/- forms.

The toggle is opt-out -- only an explicit false or 0 drops Indexes -- so
existing deployments are unaffected by the upgrade and nothing that relies on
listings loses them silently.

HTTPD_SITE_DIRECTORY_OPTIONS also gets a Dockerfile ENV default, because an
undefined config variable inside an Options directive is a hard parse error
(Illegal option ${...}) rather than the warning DirectoryIndex produces for the
same situation, and the config should still parse when Apache is invoked without
the entrypoint having run.

Verified against the published 0.4.1 image with these files overlaid, serving a
root containing index.html, somefile.txt and subdir/nested.txt with no index in
subdir. Stock 0.4.1 and the unset-overlay both return a listing for / and
/subdir/, so the upgrade is a no-op by default. Setting the variable to 0 or to
false returns 403 for both while /subdir/nested.txt still returns 200, so
enumeration is suppressed without affecting retrieval by name. Setting it to 0
alongside HTTPD_SITE_DIRECTORY_INDEX=index.html serves the index at / and 403s
/subdir/. apache2ctl configtest reports Syntax OK for all three site templates
under both rendered Options values.

Fixes #55

Signed-off-by: Nathan Klick <nathan@swirldslabs.com>
@nathanklick
nathanklick force-pushed the feat/httpd-oidc-directory-listing-toggle branch from c417512 to 217b3e0 Compare September 21, 2026 19:56
@nathanklick
nathanklick merged commit fd64a7b into main Sep 21, 2026
14 checks passed
@nathanklick
nathanklick deleted the feat/httpd-oidc-directory-listing-toggle branch September 21, 2026 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

apache-httpd-oidc: no way to disable directory listing

1 participant