openprovenance / module-media-disclosure
Metadata-driven AI disclosure for Magento 2 product images
Package info
github.com/jdlepley/magento2-ai-disclosure
Type:magento2-module
pkg:composer/openprovenance/module-media-disclosure
Requires
Requires (Dev)
None
Suggests
- symfony/process: Required only for the optional isolated C2PA executable adapter
Provides
None
Conflicts
None
Replaces
None
README
An open-source Magento 2 extension that reads declared AI/provenance metadata and keeps disclosure attached to each product-gallery image, even after derived images lose metadata.
v1.0.0. Reads declared AI metadata and displays a compact AI info ⓘ label on tagged product images. Magento's browser compression and image processing can remove source metadata; this extension transfers the supported tag and stores the disclosure against the gallery asset so it survives that processing.
The maintainer confirmed the final checks in a Magento Open Source 2.4.8-p5 / PHP 8.4.26 local sandbox, including the native admin UI, upload recovery, permissions, information button, fullscreen behavior and a clean installation. Earlier security and 20,000-image scan results are documented in validation. JetRails staging and other themes/extensions are not certified by these results.
See integration and upgrade compatibility. Magento updates can still change gallery/upload internals; this reduces coupling rather than guaranteeing future compatibility.
Screenshots
These screenshots show the extension in a local Magento test store. The gray image is a deliberately tagged test fixture: the extension reads a metadata declaration and does not decide whether an image looks AI-generated. Display labels are configurable, so saved store values may differ from the defaults.
Compact storefront disclosure
The active tagged product image has a compact AI info control. Untagged images have no automatic disclosure badge. The badge is shown in the normal product gallery and hidden in fullscreen/zoom.
Click or tap for an explanation
Clicking or tapping the information button opens the configurable explanation: "This image includes content created or modified using artificial intelligence. AI-generated elements may be combined with original photography." This wording covers images combining AI content with original product photography.
Native Magento admin review
Under Catalog > AI Disclosure, review tagged images, filter by Product SKU, Image Scope, Override Mode, Effective Disclosure or Scan Status, and inspect detection sources. Authorized editors can save an override or rescan an image. Use detected value keeps the disclosure driven by its recorded metadata result.
Store configuration
Under Stores > Configuration > Catalog > AI Disclosure, control module enablement and automatic ingestion scanning globally. Configure storefront visibility, labels and explanation text per store view. The screenshot uses Media Disclosure for the settings heading; it refers to this same module. Its displayed labels are saved example values, not a list of installation defaults.
What this version does
- Reads JPEG standard APP1 XMP and PNG XMP iTXt, including compressed iTXt.
- Maps exact
dc:subject/rdf:Bag/rdf:li = contains-synthetic-performertoAI_GENERATED_PERSON. - Keeps Magento browser compression on product-gallery uploads and writes a minimal standard XMP subject containing only
contains-synthetic-performerinto the compressed JPG/PNG when that exact declared subject is found. Other source XMP fields and unrelated tags are not copied. Existing XMP in compressed output is replaced or removed. This is not a general EXIF/GPS/ICC metadata scrubber. - Captures the received upload metadata before server validation, stages the normalized result, and associates it with the final media-gallery value ID at save.
- Retains captured disclosure on rescans of unchanged stored bytes, even if processing removed their metadata. Changed bytes are rescanned normally.
- Stores detected/effective state independently from a nullable manual override, scan status, bounded source evidence, timestamp and hash.
- Provides Catalog → AI Disclosure, with SKU lookup, per-image review, POST override/rescan and separate review/manage permissions.
- Enriches simple-product Luma gallery frames and displays a badge on the normal product-page gallery only; fullscreen/zoom hides it. Uses a layout block, the published gallery API and gallery events without polling or position measurements; labels and tooltip are store-configurable.
- Scans existing local catalog originals in keyset batches with a CLI.
- Includes an experimental adapter for the official c2patool 0.28.1, disabled by default. Signed and tampered test samples are included, with no private keys.
This reads metadata declarations, not pixels. An untagged image can still be AI-generated. XMP markers are unverified declarations. C2PA validation and signer trust are tracked separately. This extension transfers an existing declaration; it does not invent tags or establish legal compliance.
Intended compatibility
Initial staging target: patched Magento Open Source / Adobe Commerce 2.4.8, PHP 8.3/8.4, local catalog media, stock Luma simple-product gallery. Minimum engine syntax is PHP 8.3. Composer permits PHP <8.6 for development; 2.4.9/PHP 8.5 support requires its own tagged-source and runtime acceptance checks.
Not yet supported: remote-only S3 media, extended XMP, TIFF/WebP/AVIF, configurable child-gallery disclosure, Hyvä/PWA/GraphQL, media-browser-only upload routes, or external optimizers that remove metadata before a file is selected in the admin uploader. Unsupported and failed scans are visible separately from a no-marker result. Direct SQL importers need CLI rescanning.
Installation
Package name: openprovenance/module-media-disclosure. Repository name: magento2-ai-disclosure. Back up database/media and test in a matching staging store. Run commands as the Magento filesystem owner and follow the host's deployment procedure.
Composer
From your Magento root, install the package from Packagist:
composer require openprovenance/module-media-disclosure:^1.0
After installation, run the Magento setup commands below. Install the module only once: either through Composer or under app/code.
Manual installation
Copy this repository's module files into app/code/OpenProvenance/MediaDisclosure/. The repository root contains composer.json and registration.php; there is no extra module directory to copy inside that path.
Do not install the same module under both app/code and Composer vendor. For an existing manual installation, migrate it through your deployment process before requiring the Composer package.
Magento setup
After either installation method, from the Magento root:
php bin/magento module:enable OpenProvenance_MediaDisclosure php bin/magento setup:upgrade php bin/magento setup:di:compile php bin/magento setup:static-content:deploy -f en_US php bin/magento cache:clean
Deploy every locale used by the store. Magento cron/queue consumers handle normal image resizing; this module does not add a resize service. Composer installs the files; module-defined Composer scripts do not automatically run the store's setup commands.
Configuration and use
Stores → Configuration → Catalog → AI Disclosure:
- Module and automatic ingestion scanning: global.
- Storefront display, labels and tooltip: store-view scope.
- AI disclosure labels default to AI info beside the information button; the explanation opens on click/tap. Detection types remain separate internally. Non-AI provenance retains its own label, and saved store labels/tooltips override installation defaults.
Catalog → AI Disclosure:
- Open the default tagged-image list, or apply Product SKU for an exact saved SKU. Image Scope → All images also shows untagged/unscanned images.
- Review each image's detected/effective state, scan status, evidence and UTC timestamp.
- Choose an explicit disclosure or Use detected value to remove an override.
- Save override or rescan that image.
Grant Review AI Disclosure to reviewers; grant both review and Override and Rescan AI Disclosure to editors. The separate manage permission permits changes/configuration. Overrides are global to the gallery asset, including shared uses by multiple products. The CLI and automatic scanning preserve overrides. Failed scans preserve the latest successful detected/effective state.
CLI
bin/magento provenance:media:scan bin/magento provenance:media:scan --product=EXAMPLE-SKU bin/magento provenance:media:scan --force --batch-size=200
Without force, successful existing rows are skipped. Force is also needed after enabling a new provider. Errors are counted per asset and return exit status 1; unsupported formats have a separate counter. Assets are global, so a misleading --store option is deliberately not supplied. Scan local originals, not files under catalog image cache directories.
Supported metadata
| Provider / container | Recognized declaration | Normalized result | Status |
|---|---|---|---|
| XMP / JPEG standard APP1 | exact synthetic-performer subject marker | AI_GENERATED_PERSON | enabled |
| XMP / PNG iTXt | same marker | AI_GENERATED_PERSON | enabled |
| XMP / unrelated fields, comments, keywords | none | NONE, meaning no recognized declaration | enabled |
| JPEG extended XMP / other formats | no claim made | unsupported scan | limited |
| C2PA active-manifest valid source type | trainedAlgorithmicMedia | AI_GENERATED | experimental, opt-in |
| C2PA active-manifest valid source type | compositeWithTrainedAlgorithmicMedia | AI_MODIFIED | experimental, opt-in |
| C2PA other valid provenance | no recognized AI source type | PROVENANCE_PRESENT | experimental, opt-in |
| C2PA invalid or incomplete validation | not used as a valid declaration | error, prior disclosure retained | experimental |
| IPTC standalone DigitalSourceType | planned separate provider | future | not implemented |
Engine values also include AI_MODIFIED, PROVENANCE_PRESENT and UNKNOWN_AI_PROVENANCE for manual disclosure and future providers. No raw XML/manifest is persisted or rendered.
Tests
Core tests run without bootstrapping Magento or installing Composer dependencies:
php tests/run.php php tests/upload-pipeline.php npm install --prefix tests --ignore-scripts node tests/xmp-transfer.test.js node tests/gallery.test.js php -d memory_limit=8M tests/stream-reader.php
PHP requires DOM and zlib (ordinary supported Magento installations provide these). The optional live C2PA test requires Symfony Process and explicit tool/config/workdir environment variables inside an isolated execution context; see C2PA.md. Unit report-normalization tests are distinct from cryptographic verification.
See VALIDATION.md for actual completed checks and MAGENTO-ACCEPTANCE.md for the runtime release gates. PHP syntax checks are not proof of Magento compatibility. No formal coding-standard certification is claimed; local installation acceptance is maintainer-confirmed.
Architecture, roadmap and license
- Architecture and source references
- C2PA implementation and deployment tradeoffs
- Roadmap
- Contributing, Security, Changelog
This project is released under the MIT License. See LICENSE for the license terms.
OpenProvenance is the umbrella brand for projects relating to provenance. AI Disclosure for Magento 2 is the Magento extension published under that brand. Amazon-specific policies, C2PA provenance, manual disclosure and jurisdiction-specific law are separate subjects; the module reports declarations rather than asserting universal regulatory compliance.
Catalog volume and metadata privacy
The server XMP reader belongs to this extension; Magento retains its normal uploader/compression/resize pipeline. JPEG metadata is read from header segments without loading pixel data. PNG checksums are streamed through 64 KiB buffers, with only bounded XMP accumulated. PHP’s native hash_file still reads each saved/scanned file to bind disclosure evidence to its bytes. Every new image needs a metadata check; having only 50 tagged images in a 20,000-image catalog does not mean only 50 files are examined. Results, including negative scans, are saved so ordinary saves do not repeatedly scan recorded, unchanged gallery entries. Bulk scans are explicit CLI actions; no periodic scanner or per-visitor image scan is installed.
The minimal JPEG disclosure block adds 324 bytes; 50 such tagged images add 16,200 bytes total. Untagged compressed images get no additional disclosure block. Existing uploaded files are not rewritten by installing this update; re-upload from originals to apply the new transfer policy. Other metadata containers outside standard XMP are governed by the underlying uploader/optimizer and are not scrubbed by this extension.
Design rule: no Magento core replacements
Does not replace Magento core templates/classes. This is a project design rule for every release and contribution.
- Do not edit Magento core/vendor files, ship copies of core templates, use DI preferences to replace Magento classes/interfaces, or change an existing core block to an extension template.
- Add extension-owned blocks and templates through layout XML. Use Magento UI components for the admin grid and narrowly scoped plugins, observers and JavaScript mixins for integration.
- Preferences for this extension's own interfaces are allowed. Extending a Magento base class for a new extension-owned class is allowed; replacing a core class is not.
- Keep hooks narrow, preserve core behavior and test compatibility with other extensions. This rule reduces conflict risk; it does not guarantee compatibility with every extension or Magento update.
Run python3 tests/design_rules.py before releasing or submitting changes. Its checks cover DI preferences, layout template overrides and packaged core file paths. Reviewers must also check PHP-driven template changes and copied core code, which static checks cannot reliably identify.



