External plug-ins ship multi-provider (universal-schema) frameworks through a
dedicated prowler.compliance.universal entry point group, separate from the
per-provider prowler.compliance group. Both get_bulk_compliance_frameworks_universal
(loading) and get_available_compliance_frameworks (listing / --compliance
choices) scan the new group. Built-ins load first and win on a name collision;
multiple packages under the same provider are merged. load_compliance_framework
gains fatal=False so the legacy external path skips a non-legacy JSON with a
warning instead of aborting the run.
Remove a stray '=======' conflict marker left in prowler/CHANGELOG.md after
the master merge, and move the elbv2_alb_drop_invalid_header_fields_enabled
entry from Fixed to Added where it belongs.
GenericCompliance is the documented last-resort renderer, but it read the
universal attribute fields (Section, SubSection, SubGroup, Service, Type,
Comment) directly and raised AttributeError on frameworks whose schema does
not declare them (CIS, ENS, ISO27001), dropping the whole compliance CSV.
Read all six fields with getattr defaulting to None, and dedupe the finding
and manual rows into a single helper.
Resolve the provider<->models import cycle CodeQL flagged (py/cyclic-import
#7267, #7268). provider.py no longer imports models: get_output_options
stays override-only and __main__ falls back to a new default_output_options
helper in models.py when a provider does not implement it. models.py keeps
its original module-level Provider import (one-way, no cycle).
External providers that do not override get_summary_entity no longer cause
the summary table to be silently dropped. The base contract returns
(self.type, account_id), mirroring the get_output_options default.
Move the models.py Provider import (used only in the shodan path) to a
local import so models no longer depends on provider at module level. This
breaks the provider <-> models import cycle CodeQL flagged after the
generic OutputOptions default was added, and lets provider.py import
ProviderOutputOptions without a cycle. The output_file_timestamp import is
consolidated into the existing top-level config import.
External providers that do not override get_output_options no longer abort
the run with NotImplementedError. The base contract returns a generic
ProviderOutputOptions, honoring arguments.output_filename and otherwise
falling back to a provider-typed filename. Built-ins are unaffected.
- get_credentials_schema returns schemas keyed by secret type
- validate an external provider's secret against the schema for its
secret_type instead of accepting any declared schema
- reject a secret_type the provider does not declare
- Validate the secret is a JSON object before the no-schema path accepts it,
so a list/string/null cannot be persisted and fail later at {**secret}
- Add parametrized coverage for list/string/null/int payloads
- Move get_provider_type_choices into a leaf module so the provider
serializer field reuses the filters' cached list instead of recomputing
SDK provider discovery on every request
- Backfill provider_str synchronously in 0095 (single UPDATE) so the column
is populated before 0096 sets it NOT NULL, removing the Celery race
- Recreate the unique index inside 0096's transaction with a lock_timeout,
closing the duplicate-provider window left by the concurrent rebuild
- Drop migration 0097 and the now-unused backfill_provider_str task
- Reword get_class docstring: it may populate the _ep_providers cache,
rather than claiming "no global state"
- Assert ImportError specifically in the unknown-provider test to enforce
the public API contract
- Drop the unused provider_class_name left over after get_class delegation