Apply trust levels to resource reads
Pkl currently uses a mechanism called trust levels to determine if a module may import another. A module's trust level is determined based on its URI and a module may not import a module of a higher trust level. The intention of this mechanism is to prevent "remote" modules from importing "local" ones.
This mechanism does not apply to resource reads (read()) which means that modules from arbitrary HTTP(s) endpoints or from packages may read arbitrary filesystem resources that the evaluator has been allowed access to.
It would be good to treat module imports and resource reads identically here! This change will likely require a SPICE.
A major obstacle to doing so is the "converter module" pattern where a module in a package may be executed and parameterized with a local file URI to be read and processed for code generation purposes (example. Enforcing trust levels here would break this particular use case.
A way to resolve this issue is via pkl run/pkl:Command as the CLI framework is already suited for this type of use case. Unlike regular Pkl evaluation, CLI commands may trigger dynamic imports that otherwise violate trust levels only during option parsing. A similar mechanism would be introduced for executing resource reads during option parsing. Converter tools currently implemented via the pkl eval approach with external properties would be forced to migrate to pkl run with parse-time reads.
By forcing otherwise-policy-violating reads to happen through this specific interface, we eliminate many possible avenues for malicious Pkl code to exfiltrate sensitive information via resource reads.
This change is an alternative to disallowing dynamic (non-string-literal) URIs in read() operations entirely, which would negatively affect the language's flexibility, particularly around custom/external resource readers.
We might also consider exposing trust levels as an advanced evaluator setting. Currently, trust levels are only adjustable as part of Pkl's JVM API.
Source: apple/pkl