docker-compose-{up|down} make targets are available for running Image Factory.
To run:
# Generate signing key
openssl ecparam -name prime256v1 -genkey -noout -out _out/cache-signing-key.key
# Build and run
make docker-compose-up REGISTRY=127.0.0.1:5005
# Build and run (enterprise)
make docker-compose-up REGISTRY=127.0.0.1:5005 WITH_ENTERPRISE=trueTo stop:
make docker-compose-downLocal development enables authentication by default and uses the htpasswd provider.
The Compose configuration mounts hack/dev/htpasswd at the configured /etc/image-factory/htpasswd path.
When running make docker-compose-up or the integration tests, the extra extension catalog and an extra extension image and their signatures are automatically pushed to the local registry.
You can push the extra images manually with push-extra-extensions, optionally setting the EXTRA_EXTENSIONS_REGISTRY.
The extra images are located under internal/integration/testdata/extra-extensions/.
In order to run the Image Factory, generate a ECDSA key pair:
openssl ecparam -name prime256v1 -genkey -noout -out cache-signing-key.keyRun the Image Factory using the following config:
artifacts:
# registry mirror for ghcr.io
core:
registry: 127.0.0.1:5004
# private registry repository for schematics
#
# resolves to 127.0.0.1:5005/image-factory/schematic
schematic:
registry: 127.0.0.1:5005
namespace: image-factory
repository: schematic
installer:
# internal registry namespace to push installer images to
internal:
registry: 127.0.0.1:5005
namespace: siderolabs
# external registry namespace to redirect users to pull installer
external:
registry: 127.0.0.1:5005
namespace: siderolabs
cache:
oci:
# private registry repository for cached assets
registry: 127.0.0.1:5005
namespace: image-factory
repository: cache
# path to the ECDSA private key (to sign cached assets)
signingKeyPath: ./cache-signing-key.key
http:
# external URL the Image Factory is available at
externalURL: https://example.com/Authentication publishes the authoritative typed authn.Principal to the request context.
Request middleware does not keep a separate authentication identity or capture a username through an authentication callback.
After request execution, audit projects the username from that principal into audit.Record.Username.
This audit-time projection is intentional: removing legacy middleware-local username capture does not mean removing authenticated identity from audit records.
The post-authentication request context is used, not the earlier context created before authentication.
Requests rejected before authentication do not acquire an identity; public requests retain their existing audit bypass.
Audit sink failures are logged and do not change the response.
TestRequestMiddlewareOrderingAndTypedAudit protects these rules alongside contract-before-auth ordering, streaming responses, and authenticated no-store.
Operation ownership checks compare runtime descriptors with the OpenAPI document, not an expected set inferred from those descriptors. Community and Enterprise assemblies are checked with browser capability both disabled and enabled. Every enabled operation must have exactly one owner; disabled and unknown operations must have none. Enterprise contract annotations describe product availability: the token UI shell remains registered in Community, and browser routes are registered only when the provider exposes browser capability. These exceptions are explicit in the configuration tests. Counterexamples exercise missing dispatched owners, duplicates, unknown operations, and disabled capabilities.
Integration tests can be run with specific targets:
integration-directintegration-s3integration-cdnintegration-proxy-installerintegration-enterprise
Example running direct integration tests with registry mirrors (127.0.0.1:5004 is a registry mirror for ghcr.io, 127.0.0.1:5100 is an ephemeral local registry brought up by make automatically, and 127.0.0.1:5005 is a local registry for pushing images):
make integration-direct TEST_FLAGS="-test.image-registry=127.0.0.1:5004 -test.schematic-service-repository=127.0.0.1:5100/image-factory/schematic -test.installer-external-repository=127.0.0.1:5100/test -test.installer-internal-repository=127.0.0.1:5100/test -test.cache-repository=127.0.0.1:5100/image-factory/cache -test.signing-cache-repository=127.0.0.1:5100/image-factory/signing-cache -test.extra-extensions-manifest=127.0.0.1:5100/extension-testing/extensions" REGISTRY=127.0.0.1:5005A test focus can be set with:
... RUN_TESTS_DIRECT='TestIntegration/Schematic'For Enterprise tests, use the following command:
make integration-enterprise TEST_FLAGS="-test.image-registry=127.0.0.1:5004 -test.schematic-service-repository=127.0.0.1:5100/image-factory/schematic -test.installer-external-repository=127.0.0.1:5100/test -test.installer-internal-repository=127.0.0.1:5100/test -test.cache-repository=127.0.0.1:5100/image-factory/cache -test.signing-cache-repository=127.0.0.1:5100/image-factory/signing-cache -test.extra-extensions-manifest=127.0.0.1:5100/extension-testing/extensions" REGISTRY=127.0.0.1:5005(The only change is s/integration-direct/integration-enterprise/ in the target name, and the test focus variable will be RUN_TESTS_ENTERPRISE instead of RUN_TESTS_DIRECT.)