This document describes the security model implemented in iidy's YAML preprocessing import system to prevent malicious remote templates from accessing local resources.
The import system distinguishes between local templates (files loaded from the local filesystem) and remote templates (files loaded from S3, HTTP, or HTTPS URLs), applying different security restrictions to each.
- Definition: Files loaded from the local filesystem (no URL scheme)
- Examples:
config.yaml,./app.yaml,/absolute/path/config.yaml - Security: No restrictions - can import from any source type
- Rationale: Already executing in a trusted local context
- Definition: Files loaded from S3, HTTP, or HTTPS URLs
- Examples:
s3://bucket/config.yaml,https://example.com/config.yaml - Security: Subject to restrictions to prevent local resource access
- Rationale: Untrusted external content should not access local resources
| Import Type | Description | Security Risk |
|---|---|---|
file: |
Local filesystem access | Could read sensitive files |
env: |
Local environment variables | Could access secrets/credentials |
git: |
Local git repository access | Could extract repository information |
filehash: |
File hashing (typically local files) | Could scan filesystem structure |
filehash-base64: |
File hashing with base64 encoding | Could scan filesystem structure |
| Import Type | Description | Use Case |
|---|---|---|
s3: |
S3 objects | Access other S3-stored configurations |
http:/https: |
HTTP endpoints | Fetch configuration from web APIs |
cfn: |
CloudFormation stacks and exports | Dynamic AWS resource references |
ssm: |
SSM parameters | Centralized configuration management |
ssm-path: |
SSM parameter paths | Bulk parameter retrieval |
random: |
Random value generation | Generate unique identifiers |
When a template uses relative imports (no explicit type prefix), the import inherits the type of the parent template:
# From s3://bucket/configs/app.yaml
$imports:
database: "database.yaml" # Resolves to s3://bucket/configs/database.yaml (inherits S3)Explicit local path indicators are forbidden from remote templates:
# From s3://bucket/config.yaml - These will be REJECTED:
$imports:
bad1: "./local.yaml" # Error: local path from remote
bad2: "../local.yaml" # Error: local path from remote
bad3: "/abs/local.yaml" # Error: local path from remote# From https://example.com/configs/app.yaml
$imports:
s3data: "s3://bucket/data.yaml" # S3 import
webdata: "https://api.com/config.json" # HTTP import
database: "database.yaml" # Relative (inherits HTTPS)
cfnstack: "cfn:stack/MyStack/output" # CloudFormation
secret: "ssm:/app/secret" # SSM parameter
uuid: "random:dashed-name" # Random generation# From s3://bucket/config.yaml - All of these are REJECTED:
$imports:
localfile: "file:./local.yaml" # File access forbidden
envvar: "env:HOME" # Environment variable forbidden
gitinfo: "git:branch" # Git repository forbidden
hash: "filehash:./data.txt" # Local file hash forbidden
localpath: "./local.yaml" # Local path indicator forbidden# From local file ./config.yaml - All imports allowed:
$imports:
localfile: "file:./other.yaml" # Local file
envvar: "env:HOME" # Environment variable
s3data: "s3://bucket/data.yaml" # S3 object
webdata: "https://api.com/data" # HTTP endpoint
gitbranch: "git:branch" # Git info
hash: "filehash:./data.txt" # File hashThe system derives base paths to enable relative imports across different contexts:
/Users/app/configs/main.yaml->/Users/app/configs/./configs/app.yaml->./configs/config.yaml-> `` (empty - current directory)
s3://bucket/file.yaml->s3://bucket/s3://bucket/configs/app.yaml->s3://bucket/configs/s3://bucket/configs/env/prod.yaml->s3://bucket/configs/env/
https://example.com/file.yaml->https://example.com/https://example.com/configs/app.yaml->https://example.com/configs/http://api.com/templates/base.yaml->http://api.com/templates/
- Credential Theft: Prevents remote templates from reading environment variables containing secrets
- File System Scanning: Blocks access to local files and directory structures
- Information Disclosure: Prevents extraction of git repository information
- Privilege Escalation: Stops remote templates from accessing local resources beyond their intended scope
- Legitimate Composition: Remote templates can compose from other remote sources
- Relative Imports: Templates can reference related files in the same remote context
- AWS Integration: Remote templates can access CloudFormation and SSM for dynamic configuration
- Local Flexibility: Local templates retain full import capabilities for trusted operations
When a security violation is detected, the system returns a clear error message:
Import type 'file:./local.yaml' in 's3://bucket/config.yaml' not allowed from remote template
This helps developers understand why their import was rejected and how to fix it.
- Security validation occurs in the
parse_import_type()function insrc/yaml/imports/mod.rs - Base path derivation happens in
TagContext::from_processing_env()insrc/yaml/resolution/resolver.rs - The security model is extensively tested with over 150 test cases covering various scenarios
- The implementation follows the principle of "secure by default" - remote templates are restricted unless explicitly allowed