{"data":{"skill":{"slug":"artemxtech-tasknotes","name":"tasknotes","icon":"📦","repo":"https://github.com/ArtemXTech/personal-os-skills/tree/main/skills/tasknotes","status":"approved","author":"ArtemXTech","authorVersion":null,"skillstoreRevision":null},"audit":{"id":"0e725ecb-1cbf-4ba5-b959-5d51ea60725f","skill_id":"1933699a-e180-4527-b819-30a18f1c94c5","version":8,"content_hash":"v2:1b5b6c4962b2ad5a7a34603cab2685bbbd1b61ef:7b0a1d3dc5dde2d69ac5f28c86e7b1a887a62e3a68c0742cba2b9a309e36b086:7798af88d675a38155747ea58865d480cfad94de24cb47a8afe90c551fda3a0b:442f77a5241f43e6a60172539a5cd0f3","risk_level":"high","is_blocked":false,"safe_to_publish":false,"analysis_status":"ok","agent_auto_install_policy":"confirmation_required","manual_install_policy":"allowed","summary":"The skill intentionally runs local CLI commands and uses the TaskNotes localhost HTTP API to read, create, update, and delete Obsidian tasks. No prompt injection or external cloud endpoint was found, but the skill handles an API token, loads a vault-root .env file, and has mutating and destructive task operations.","remediation":[{"issue":"API port value is not validated before URL construction.","severity":"high","suggestion":"Parse TASKNOTES_API_PORT as an integer from 1 to 65535 and reject values containing URL metacharacters before building BASE_URL."},{"issue":"The script loads a vault-root .env file.","severity":"high","suggestion":"Use a skill-specific config file or read only explicit process variables, and document that unrelated secrets should not be placed in that .env file."},{"issue":"Delete operations have no built-in confirmation or dry run.","severity":"medium","suggestion":"Require a --force flag, add a confirmation prompt for interactive use, or prefer archive behavior when the TaskNotes API supports it."},{"issue":"The skill documents mutating shell commands for agents.","severity":"medium","suggestion":"State that create, update, and delete commands should be confirmed by the user before execution in agent workflows."}],"risk_factor_evidence":[{"factor":"network","evidence":[{"file":"scripts/tasks.py","line_end":49,"line_start":49},{"file":"scripts/tasks.py","line_end":53,"line_start":53},{"file":"scripts/tasks.py","line_end":83,"line_start":83},{"file":"scripts/tasks.py","line_end":152,"line_start":152},{"file":"scripts/tasks.py","line_end":189,"line_start":189},{"file":"scripts/tasks.py","line_end":206,"line_start":206},{"file":"scripts/tasks.py","line_end":219,"line_start":219},{"file":"scripts/tasks.py","line_end":238,"line_start":238},{"file":"scripts/tasks.py","line_end":53,"line_start":53},{"file":"scripts/tasks.py","line_end":58,"line_start":58},{"file":"scripts/tasks.py","line_end":60,"line_start":60},{"file":"scripts/tasks.py","line_end":39,"line_start":39},{"file":"SKILL.md","line_end":77,"line_start":77}]},{"factor":"env_access","evidence":[{"file":"scripts/tasks.py","line_end":37,"line_start":37},{"file":"scripts/tasks.py","line_end":38,"line_start":38},{"file":"scripts/tasks.py","line_end":37,"line_start":37},{"file":"scripts/tasks.py","line_end":38,"line_start":38},{"file":"scripts/tasks.py","line_end":4,"line_start":4},{"file":"scripts/tasks.py","line_end":30,"line_start":30},{"file":"scripts/tasks.py","line_end":35,"line_start":35},{"file":"scripts/tasks.py","line_end":30,"line_start":30},{"file":"scripts/tasks.py","line_end":35,"line_start":35},{"file":"scripts/tasks.py","line_end":18,"line_start":18},{"file":"scripts/tasks.py","line_end":37,"line_start":37},{"file":"scripts/tasks.py","line_end":44,"line_start":44},{"file":"scripts/tasks.py","line_end":45,"line_start":45},{"file":"SKILL.md","line_end":21,"line_start":21}]},{"factor":"external_commands","evidence":[{"file":"SKILL.md","line_end":18,"line_start":18},{"file":"SKILL.md","line_end":22,"line_start":19},{"file":"SKILL.md","line_end":23,"line_start":22},{"file":"SKILL.md","line_end":27,"line_start":23},{"file":"SKILL.md","line_end":57,"line_start":27},{"file":"SKILL.md","line_end":61,"line_start":57},{"file":"SKILL.md","line_end":62,"line_start":61},{"file":"SKILL.md","line_end":64,"line_start":62},{"file":"SKILL.md","line_end":67,"line_start":64},{"file":"SKILL.md","line_end":67,"line_start":67},{"file":"SKILL.md","line_end":68,"line_start":68},{"file":"SKILL.md","line_end":70,"line_start":69},{"file":"SKILL.md","line_end":71,"line_start":70},{"file":"SKILL.md","line_end":72,"line_start":71},{"file":"SKILL.md","line_end":73,"line_start":72},{"file":"SKILL.md","line_end":77,"line_start":73},{"file":"SKILL.md","line_end":90,"line_start":77},{"file":"SKILL.md","line_end":91,"line_start":90},{"file":"SKILL.md","line_end":92,"line_start":91},{"file":"SKILL.md","line_end":93,"line_start":92},{"file":"SKILL.md","line_end":94,"line_start":93},{"file":"SKILL.md","line_end":95,"line_start":94},{"file":"SKILL.md","line_end":96,"line_start":95},{"file":"SKILL.md","line_end":97,"line_start":96},{"file":"SKILL.md","line_end":109,"line_start":97},{"file":"SKILL.md","line_end":121,"line_start":109}]}],"critical_findings":[],"high_findings":[{"title":"dotenv library","locations":[{"file":"scripts/tasks.py","line_end":35,"line_start":35}],"confidence":0.92,"description":"load_dotenv(VAULT_ROOT / \".env\")","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"load_dotenv reads a .env file from the computed vault root. This can load sensitive variables into the process."},{"title":"Python dotenv loader","locations":[{"file":"scripts/tasks.py","line_end":35,"line_start":35}],"confidence":0.92,"description":"load_dotenv(VAULT_ROOT / \".env\")","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"The loader reads the vault-root .env file before any command is executed. This is real environment file access, not a placeholder."},{"title":"Generic API/secret keys","locations":[{"file":"scripts/tasks.py","line_end":37,"line_start":37}],"confidence":0.78,"description":"API_KEY = os.getenv(\"TASKNOTES_API_KEY\")","review_kind":"capability","source_category":"env_access","source_severity":"high","confidence_reasoning":"No secret is hardcoded, but the code reads TASKNOTES_API_KEY from the environment. A community skill handling API tokens is security-sensitive."},{"title":"Generic API/secret keys","locations":[{"file":"scripts/tasks.py","line_end":44,"line_start":44}],"confidence":0.74,"description":"if API_KEY:","review_kind":"capability","source_category":"env_access","source_severity":"high","confidence_reasoning":"The conditional shows API_KEY is used in the request flow when present. This confirms runtime credential handling, although the value is user supplied."},{"title":"Generic API/secret keys","locations":[{"file":"scripts/tasks.py","line_end":45,"line_start":45}],"confidence":0.82,"description":"headers[\"Authorization\"] = f\"Bearer {API_KEY}\"","review_kind":"capability","source_category":"env_access","source_severity":"high","confidence_reasoning":"The API key is placed into an Authorization bearer header for HTTP requests. If the endpoint is misconfigured, the token could be exposed."},{"title":"Environment file access","locations":[{"file":"scripts/tasks.py","line_end":32,"line_start":32}],"confidence":0.82,"description":"# Load .env from vault root","review_kind":"security","source_category":"sensitive","source_severity":"high","confidence_reasoning":"The comment describes loading .env from the vault root, and the following code performs that load. A vault-root environment file may contain unrelated secrets."},{"title":"Environment file access","locations":[{"file":"scripts/tasks.py","line_end":35,"line_start":35}],"confidence":0.93,"description":"load_dotenv(VAULT_ROOT / \".env\")","review_kind":"security","source_category":"sensitive","source_severity":"high","confidence_reasoning":"load_dotenv(VAULT_ROOT / \".env\") reads an environment file outside the skill directory. This is sensitive file access in a community skill."},{"title":"Environment file access","locations":[{"file":"SKILL.md","line_end":18,"line_start":18}],"confidence":0.72,"description":"3. **Environment variables** in `.env` file at vault root (if using auth):","review_kind":"security","source_category":"sensitive","source_severity":"high","confidence_reasoning":"The documentation instructs users to keep TaskNotes API configuration in a vault-root .env file. This is sensitive configuration guidance, though the actual file read is in scripts/tasks.py."},{"title":"Unvalidated API Port Can Redirect Authenticated Requests","locations":[{"file":"scripts/tasks.py","line_end":39,"line_start":37},{"file":"scripts/tasks.py","line_end":45,"line_start":42},{"file":"scripts/tasks.py","line_end":54,"line_start":53}],"confidence":0.76,"description":"TASKNOTES_API_PORT is inserted into BASE_URL without numeric validation, and TASKNOTES_API_KEY is sent as a bearer header. A crafted port value could change URL parsing and send task data or the token away from localhost.","review_kind":"security","source_category":"semantic","source_severity":"high","confidence_reasoning":"The code directly interpolates API_PORT into an HTTP URL and sends headers through requests. Exploitation requires malicious environment or config control, so confidence is high but not absolute."}],"medium_findings":[{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":152,"line_start":152}],"confidence":0.88,"description":"result = api_request(\"POST\", \"/tasks\", data=data)","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"POST /tasks creates TaskNotes entries through the local API. This is an intended but mutating network operation against the user vault."},{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":189,"line_start":189}],"confidence":0.88,"description":"result = api_request(\"PUT\", f\"/tasks/{task_id}\", data=data)","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"PUT /tasks/{id} updates existing task records through the local API. This can alter task metadata and body details in the vault."},{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":206,"line_start":206}],"confidence":0.9,"description":"result = api_request(\"DELETE\", f\"/tasks/{task_id}\")","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"DELETE /tasks/{id} removes a task through the local API. This is a destructive operation even though it is part of the skill purpose."},{"title":"Python getenv function","locations":[{"file":"scripts/tasks.py","line_end":37,"line_start":37}],"confidence":0.82,"description":"API_KEY = os.getenv(\"TASKNOTES_API_KEY\")","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"The script reads TASKNOTES_API_KEY from the environment for API authentication. This is legitimate, but it is real access to sensitive configuration."},{"title":"getenv function call","locations":[{"file":"scripts/tasks.py","line_end":37,"line_start":37}],"confidence":0.82,"description":"API_KEY = os.getenv(\"TASKNOTES_API_KEY\")","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"os.getenv reads TASKNOTES_API_KEY, which can contain an authentication token. The value is later used in the Authorization header."},{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":57,"line_start":27}],"confidence":0.87,"description":"```bash","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The bash block documents uv run scripts/tasks.py commands that agents may execute, including create, update, and delete. The commands are local and purposeful, but external command execution is real."},{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":64,"line_start":62}],"confidence":0.83,"description":"```bash","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The fenced bash example runs uv run scripts/tasks.py options --table. This is local command execution for discovery of configured TaskNotes values."},{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":121,"line_start":109}],"confidence":0.88,"description":"```bash","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The workflow bash block instructs running local CLI commands that list, create, and update TaskNotes tasks. This confirms intended external command use with mutating effects."},{"title":"Destructive Task Deletion Without Confirmation","locations":[{"file":"SKILL.md","line_end":50,"line_start":49},{"file":"scripts/tasks.py","line_end":206,"line_start":203}],"confidence":0.92,"description":"The CLI exposes a delete command that calls DELETE /tasks/{id} without an in-script confirmation, dry-run, or soft-delete safeguard. A mistaken task path can remove a TaskNotes task from the vault.","review_kind":"security","source_category":"semantic","source_severity":"medium","confidence_reasoning":"The documented delete command maps directly to a DELETE API request in code. No confirmation or recovery safeguard is visible in the cited lines."}],"low_findings":[{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":49,"line_start":49}],"confidence":0.82,"description":"def api_request(method: str, endpoint: str, params: dict = None, data: dict = None):","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"api_request constructs HTTP calls to the TaskNotes API and is used by list, create, update, delete, stats, and options commands. The endpoint is intended for localhost, but this confirms network access to task data."},{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":53,"line_start":53}],"confidence":0.9,"description":"response = requests.request(","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"requests.request sends parameters, JSON bodies, and headers to BASE_URL. The URL is intended for localhost, but the skill performs real HTTP network I/O."},{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":83,"line_start":83}],"confidence":0.88,"description":"result = api_request(\"GET\", \"/tasks\", params=params)","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"GET /tasks reads TaskNotes task metadata from the local Obsidian API. This is intended behavior, but it confirms task data access over HTTP."},{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":219,"line_start":219}],"confidence":0.84,"description":"result = api_request(\"GET\", \"/stats\")","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"GET /stats reads aggregate task information from the local API. It is low risk, but it is still network access to user task data."},{"title":"HTTP client library","locations":[{"file":"scripts/tasks.py","line_end":238,"line_start":238}],"confidence":0.84,"description":"result = api_request(\"GET\", \"/filter-options\")","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"GET /filter-options reads project, status, and priority metadata from TaskNotes. It is expected local API access, not external exfiltration."},{"title":"Python HTTP libraries","locations":[{"file":"scripts/tasks.py","line_end":53,"line_start":53}],"confidence":0.9,"description":"response = requests.request(","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"The requests library is used to send actual HTTP requests to BASE_URL. Context shows the calls target the local TaskNotes API."},{"title":"Hardcoded URL","locations":[{"file":"scripts/tasks.py","line_end":39,"line_start":39}],"confidence":0.78,"description":"BASE_URL = f\"http://localhost:{API_PORT}/api\"","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"BASE_URL hardcodes an HTTP localhost API endpoint with an environment-supplied port. It is not an external domain, but it confirms local HTTP API use."},{"title":"Python getenv function","locations":[{"file":"scripts/tasks.py","line_end":38,"line_start":38}],"confidence":0.72,"description":"API_PORT = os.getenv(\"TASKNOTES_API_PORT\", \"8080\")","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"The script reads TASKNOTES_API_PORT from the environment and uses it to construct the API URL. This is configuration access that influences the network target."},{"title":"getenv function call","locations":[{"file":"scripts/tasks.py","line_end":38,"line_start":38}],"confidence":0.72,"description":"API_PORT = os.getenv(\"TASKNOTES_API_PORT\", \"8080\")","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"os.getenv reads TASKNOTES_API_PORT and feeds endpoint construction. The value is not a secret, but it controls connection behavior."},{"title":"dotenv library","locations":[{"file":"scripts/tasks.py","line_end":30,"line_start":30}],"confidence":0.68,"description":"from dotenv import load_dotenv","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"The dotenv import enables the load_dotenv call later in the file. By itself it is not dangerous, but context confirms environment-file support."},{"title":"Python dotenv loader","locations":[{"file":"scripts/tasks.py","line_end":30,"line_start":30}],"confidence":0.68,"description":"from dotenv import load_dotenv","review_kind":"capability","source_category":"env_access","source_severity":"low","confidence_reasoning":"The python-dotenv import is part of an actual dotenv loading flow at line 35. It confirms environment-file handling in the skill."},{"title":"Hardcoded URL","locations":[{"file":"SKILL.md","line_end":77,"line_start":77}],"confidence":0.8,"description":"Base URL: `http://localhost:8080/api`","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"The skill documents http://localhost:8080/api as its base endpoint. It is local rather than external, but it confirms dependence on a plaintext local HTTP API."}],"dangerous_patterns":[],"files_scanned":2,"total_lines":447,"audit_model":"codex","audited_at":"2026-07-07T19:53:53.238+00:00","created_at":"2026-07-08T00:39:04.377526+00:00","static_findings":[{"id":"network:scripts/tasks.py:49:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"def api_request(method: str, endpoint: str, params: dict = None, data: dict = None):","category":"network","line_end":49,"severity":"low","line_start":49},{"id":"network:scripts/tasks.py:53:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"response = requests.request(","category":"network","line_end":53,"severity":"low","line_start":53},{"id":"network:scripts/tasks.py:83:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"result = api_request(\"GET\", \"/tasks\", params=params)","category":"network","line_end":83,"severity":"low","line_start":83},{"id":"network:scripts/tasks.py:152:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"result = api_request(\"POST\", \"/tasks\", data=data)","category":"network","line_end":152,"severity":"low","line_start":152},{"id":"network:scripts/tasks.py:189:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"result = api_request(\"PUT\", f\"/tasks/{task_id}\", data=data)","category":"network","line_end":189,"severity":"low","line_start":189},{"id":"network:scripts/tasks.py:206:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"result = api_request(\"DELETE\", f\"/tasks/{task_id}\")","category":"network","line_end":206,"severity":"low","line_start":206},{"id":"network:scripts/tasks.py:219:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"result = api_request(\"GET\", \"/stats\")","category":"network","line_end":219,"severity":"low","line_start":219},{"id":"network:scripts/tasks.py:238:http-client-library","file":"scripts/tasks.py","pattern":"HTTP client library","snippet":"result = api_request(\"GET\", \"/filter-options\")","category":"network","line_end":238,"severity":"low","line_start":238},{"id":"network:scripts/tasks.py:53:python-http-libraries","file":"scripts/tasks.py","pattern":"Python HTTP libraries","snippet":"response = requests.request(","category":"network","line_end":53,"severity":"low","line_start":53},{"id":"network:scripts/tasks.py:58:python-http-libraries","file":"scripts/tasks.py","pattern":"Python HTTP libraries","snippet":"except requests.exceptions.ConnectionError:","category":"network","line_end":58,"severity":"low","line_start":58},{"id":"network:scripts/tasks.py:60:python-http-libraries","file":"scripts/tasks.py","pattern":"Python HTTP libraries","snippet":"except requests.exceptions.HTTPError as e:","category":"network","line_end":60,"severity":"low","line_start":60},{"id":"network:scripts/tasks.py:39:hardcoded-url","file":"scripts/tasks.py","pattern":"Hardcoded URL","snippet":"BASE_URL = f\"http://localhost:{API_PORT}/api\"","category":"network","line_end":39,"severity":"low","line_start":39},{"id":"env_access:scripts/tasks.py:37:python-getenv-function","file":"scripts/tasks.py","pattern":"Python getenv function","snippet":"API_KEY = os.getenv(\"TASKNOTES_API_KEY\")","category":"env_access","line_end":37,"severity":"low","line_start":37},{"id":"env_access:scripts/tasks.py:38:python-getenv-function","file":"scripts/tasks.py","pattern":"Python getenv function","snippet":"API_PORT = os.getenv(\"TASKNOTES_API_PORT\", \"8080\")","category":"env_access","line_end":38,"severity":"low","line_start":38},{"id":"env_access:scripts/tasks.py:37:getenv-function-call","file":"scripts/tasks.py","pattern":"getenv function call","snippet":"API_KEY = os.getenv(\"TASKNOTES_API_KEY\")","category":"env_access","line_end":37,"severity":"low","line_start":37},{"id":"env_access:scripts/tasks.py:38:getenv-function-call","file":"scripts/tasks.py","pattern":"getenv function call","snippet":"API_PORT = os.getenv(\"TASKNOTES_API_PORT\", \"8080\")","category":"env_access","line_end":38,"severity":"low","line_start":38},{"id":"env_access:scripts/tasks.py:4:dotenv-library","file":"scripts/tasks.py","pattern":"dotenv library","snippet":"# dependencies = [\"requests\", \"python-dotenv\"]","category":"env_access","line_end":4,"severity":"low","line_start":4},{"id":"env_access:scripts/tasks.py:30:dotenv-library","file":"scripts/tasks.py","pattern":"dotenv library","snippet":"from dotenv import load_dotenv","category":"env_access","line_end":30,"severity":"low","line_start":30},{"id":"env_access:scripts/tasks.py:35:dotenv-library","file":"scripts/tasks.py","pattern":"dotenv library","snippet":"load_dotenv(VAULT_ROOT / \".env\")","category":"env_access","line_end":35,"severity":"low","line_start":35},{"id":"env_access:scripts/tasks.py:30:python-dotenv-loader","file":"scripts/tasks.py","pattern":"Python dotenv loader","snippet":"from dotenv import load_dotenv","category":"env_access","line_end":30,"severity":"low","line_start":30},{"id":"env_access:scripts/tasks.py:35:python-dotenv-loader","file":"scripts/tasks.py","pattern":"Python dotenv loader","snippet":"load_dotenv(VAULT_ROOT / \".env\")","category":"env_access","line_end":35,"severity":"low","line_start":35},{"id":"env_access:scripts/tasks.py:18:generic-api-secret-keys","file":"scripts/tasks.py","pattern":"Generic API/secret keys","snippet":"TASKNOTES_API_KEY - API authentication token (optional, depends on TaskNotes settings)","category":"env_access","line_end":18,"severity":"high","line_start":18},{"id":"env_access:scripts/tasks.py:37:generic-api-secret-keys","file":"scripts/tasks.py","pattern":"Generic API/secret keys","snippet":"API_KEY = os.getenv(\"TASKNOTES_API_KEY\")","category":"env_access","line_end":37,"severity":"high","line_start":37},{"id":"env_access:scripts/tasks.py:44:generic-api-secret-keys","file":"scripts/tasks.py","pattern":"Generic API/secret keys","snippet":"if API_KEY:","category":"env_access","line_end":44,"severity":"high","line_start":44},{"id":"env_access:scripts/tasks.py:45:generic-api-secret-keys","file":"scripts/tasks.py","pattern":"Generic API/secret keys","snippet":"headers[\"Authorization\"] = f\"Bearer {API_KEY}\"","category":"env_access","line_end":45,"severity":"high","line_start":45},{"id":"sensitive:scripts/tasks.py:32:environment-file-access","file":"scripts/tasks.py","pattern":"Environment file access","snippet":"# Load .env from vault root","category":"sensitive","line_end":32,"severity":"high","line_start":32},{"id":"sensitive:scripts/tasks.py:35:environment-file-access","file":"scripts/tasks.py","pattern":"Environment file access","snippet":"load_dotenv(VAULT_ROOT / \".env\")","category":"sensitive","line_end":35,"severity":"high","line_start":35},{"id":"blocker:scripts/tasks.py:169:system-reconnaissance","file":"scripts/tasks.py","pattern":"System reconnaissance","snippet":"task_id = urllib.parse.quote(args.task_id, safe=\"\")","category":"blocker","line_end":169,"severity":"low","line_start":169},{"id":"blocker:scripts/tasks.py:205:system-reconnaissance","file":"scripts/tasks.py","pattern":"System reconnaissance","snippet":"task_id = urllib.parse.quote(args.task_id, safe=\"\")","category":"blocker","line_end":205,"severity":"low","line_start":205},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"3. **Environment variables** in `.env` file at vault root (if using auth):","category":"external_commands","line_end":18,"severity":"medium","line_start":18},{"id":"external_commands:SKILL.md:19:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":22,"severity":"medium","line_start":19},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":23,"severity":"medium","line_start":22},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"If TaskNotes has no auth token set, you don't need a `.env` file.","category":"external_commands","line_end":27,"severity":"medium","line_start":23},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":57,"severity":"medium","line_start":27},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":61,"severity":"medium","line_start":57},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Status and Priority values:** Configured in your TaskNotes plugin settings. Run `options` command ","category":"external_commands","line_end":62,"severity":"medium","line_start":61},{"id":"external_commands:SKILL.md:62:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":64,"severity":"medium","line_start":62},{"id":"external_commands:SKILL.md:64:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":67,"severity":"medium","line_start":64},{"id":"external_commands:SKILL.md:67:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `projects` - Array of project links, e.g. `[\"[[Project Name]]\"]`","category":"external_commands","line_end":67,"severity":"medium","line_start":67},{"id":"external_commands:SKILL.md:68:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `contexts` - Array like `[\"office\", \"energy-high\"]`","category":"external_commands","line_end":68,"severity":"medium","line_start":68},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `due` - Due date (YYYY-MM-DD)","category":"external_commands","line_end":70,"severity":"medium","line_start":69},{"id":"external_commands:SKILL.md:70:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `scheduled` - Scheduled date/time (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS)","category":"external_commands","line_end":71,"severity":"medium","line_start":70},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `timeEstimate` - Minutes (number)","category":"external_commands","line_end":72,"severity":"medium","line_start":71},{"id":"external_commands:SKILL.md:72:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `tags` - Array of tags","category":"external_commands","line_end":73,"severity":"medium","line_start":72},{"id":"external_commands:SKILL.md:73:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `details` - Task description (writes to markdown body, not frontmatter)","category":"external_commands","line_end":77,"severity":"medium","line_start":73},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Base URL: `http://localhost:8080/api`","category":"external_commands","line_end":90,"severity":"medium","line_start":77},{"id":"external_commands:SKILL.md:90:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `status` - Filter by status","category":"external_commands","line_end":91,"severity":"medium","line_start":90},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `project` - Filter by project name","category":"external_commands","line_end":92,"severity":"medium","line_start":91},{"id":"external_commands:SKILL.md:92:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `priority` - Filter by priority","category":"external_commands","line_end":93,"severity":"medium","line_start":92},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `tag` - Filter by tag","category":"external_commands","line_end":94,"severity":"medium","line_start":93},{"id":"external_commands:SKILL.md:94:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `overdue` - true/false","category":"external_commands","line_end":95,"severity":"medium","line_start":94},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `sort` - Sort field","category":"external_commands","line_end":96,"severity":"medium","line_start":95},{"id":"external_commands:SKILL.md:96:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `limit` - Max results","category":"external_commands","line_end":97,"severity":"medium","line_start":96},{"id":"external_commands:SKILL.md:97:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `offset` - Pagination offset","category":"external_commands","line_end":109,"severity":"medium","line_start":97},{"id":"external_commands:SKILL.md:109:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":121,"severity":"medium","line_start":109},{"id":"network:SKILL.md:77:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"Base URL: `http://localhost:8080/api`","category":"network","line_end":77,"severity":"low","line_start":77},{"id":"env_access:SKILL.md:21:generic-api-secret-keys","file":"SKILL.md","pattern":"Generic API/secret keys","snippet":"TASKNOTES_API_KEY=your_token_here","category":"env_access","line_end":21,"severity":"high","line_start":21},{"id":"sensitive:SKILL.md:18:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"3. **Environment variables** in `.env` file at vault root (if using auth):","category":"sensitive","line_end":18,"severity":"high","line_start":18},{"id":"sensitive:SKILL.md:23:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"If TaskNotes has no auth token set, you don't need a `.env` file.","category":"sensitive","line_end":23,"severity":"high","line_start":23},{"id":"blocker:SKILL.md:103:network-reconnaissance","file":"SKILL.md","pattern":"Network reconnaissance","snippet":"- \"show in-progress tasks\" → list --status in-progress","category":"blocker","line_end":104,"severity":"low","line_start":103},{"id":"blocker:SKILL.md:111:network-reconnaissance","file":"SKILL.md","pattern":"Network reconnaissance","snippet":"uv run scripts/tasks.py list --status in-progress --table","category":"blocker","line_end":111,"severity":"low","line_start":111}],"finding_verdicts":[{"id":"network:scripts/tasks.py:49:http-client-library","reason":"api_request constructs HTTP calls to the TaskNotes API and is used by list, create, update, delete, stats, and options commands. The endpoint is intended for localhost, but this confirms network access to task data.","verdict":"confirmed","severity":"low","confidence":0.82},{"id":"network:scripts/tasks.py:53:http-client-library","reason":"requests.request sends parameters, JSON bodies, and headers to BASE_URL. The URL is intended for localhost, but the skill performs real HTTP network I/O.","verdict":"confirmed","severity":"low","confidence":0.9},{"id":"network:scripts/tasks.py:83:http-client-library","reason":"GET /tasks reads TaskNotes task metadata from the local Obsidian API. This is intended behavior, but it confirms task data access over HTTP.","verdict":"confirmed","severity":"low","confidence":0.88},{"id":"network:scripts/tasks.py:152:http-client-library","reason":"POST /tasks creates TaskNotes entries through the local API. This is an intended but mutating network operation against the user vault.","verdict":"confirmed","severity":"medium","confidence":0.88},{"id":"network:scripts/tasks.py:189:http-client-library","reason":"PUT /tasks/{id} updates existing task records through the local API. This can alter task metadata and body details in the vault.","verdict":"confirmed","severity":"medium","confidence":0.88},{"id":"network:scripts/tasks.py:206:http-client-library","reason":"DELETE /tasks/{id} removes a task through the local API. This is a destructive operation even though it is part of the skill purpose.","verdict":"confirmed","severity":"medium","confidence":0.9},{"id":"network:scripts/tasks.py:219:http-client-library","reason":"GET /stats reads aggregate task information from the local API. It is low risk, but it is still network access to user task data.","verdict":"confirmed","severity":"low","confidence":0.84},{"id":"network:scripts/tasks.py:238:http-client-library","reason":"GET /filter-options reads project, status, and priority metadata from TaskNotes. It is expected local API access, not external exfiltration.","verdict":"confirmed","severity":"low","confidence":0.84},{"id":"network:scripts/tasks.py:53:python-http-libraries","reason":"The requests library is used to send actual HTTP requests to BASE_URL. Context shows the calls target the local TaskNotes API.","verdict":"confirmed","severity":"low","confidence":0.9},{"id":"network:scripts/tasks.py:58:python-http-libraries","reason":"This line only catches requests.exceptions.ConnectionError. It does not initiate a network request or transfer data.","verdict":"false_positive","confidence":0.96},{"id":"network:scripts/tasks.py:60:python-http-libraries","reason":"This line only catches requests.exceptions.HTTPError. It is error handling, not a network operation.","verdict":"false_positive","confidence":0.96},{"id":"network:scripts/tasks.py:39:hardcoded-url","reason":"BASE_URL hardcodes an HTTP localhost API endpoint with an environment-supplied port. It is not an external domain, but it confirms local HTTP API use.","verdict":"confirmed","severity":"low","confidence":0.78},{"id":"env_access:scripts/tasks.py:37:python-getenv-function","reason":"The script reads TASKNOTES_API_KEY from the environment for API authentication. This is legitimate, but it is real access to sensitive configuration.","verdict":"confirmed","severity":"medium","confidence":0.82},{"id":"env_access:scripts/tasks.py:38:python-getenv-function","reason":"The script reads TASKNOTES_API_PORT from the environment and uses it to construct the API URL. This is configuration access that influences the network target.","verdict":"confirmed","severity":"low","confidence":0.72},{"id":"env_access:scripts/tasks.py:37:getenv-function-call","reason":"os.getenv reads TASKNOTES_API_KEY, which can contain an authentication token. The value is later used in the Authorization header.","verdict":"confirmed","severity":"medium","confidence":0.82},{"id":"env_access:scripts/tasks.py:38:getenv-function-call","reason":"os.getenv reads TASKNOTES_API_PORT and feeds endpoint construction. The value is not a secret, but it controls connection behavior.","verdict":"confirmed","severity":"low","confidence":0.72},{"id":"env_access:scripts/tasks.py:4:dotenv-library","reason":"This is only a script dependency declaration for python-dotenv. Actual environment file loading is covered by the load_dotenv findings.","verdict":"false_positive","confidence":0.9},{"id":"env_access:scripts/tasks.py:30:dotenv-library","reason":"The dotenv import enables the load_dotenv call later in the file. By itself it is not dangerous, but context confirms environment-file support.","verdict":"confirmed","severity":"low","confidence":0.68},{"id":"env_access:scripts/tasks.py:35:dotenv-library","reason":"load_dotenv reads a .env file from the computed vault root. This can load sensitive variables into the process.","verdict":"confirmed","severity":"high","confidence":0.92},{"id":"env_access:scripts/tasks.py:30:python-dotenv-loader","reason":"The python-dotenv import is part of an actual dotenv loading flow at line 35. It confirms environment-file handling in the skill.","verdict":"confirmed","severity":"low","confidence":0.68},{"id":"env_access:scripts/tasks.py:35:python-dotenv-loader","reason":"The loader reads the vault-root .env file before any command is executed. This is real environment file access, not a placeholder.","verdict":"confirmed","severity":"high","confidence":0.92},{"id":"env_access:scripts/tasks.py:18:generic-api-secret-keys","reason":"The docstring names TASKNOTES_API_KEY but does not include a credential value. No hardcoded secret is present on this line.","verdict":"false_positive","confidence":0.94},{"id":"env_access:scripts/tasks.py:37:generic-api-secret-keys","reason":"No secret is hardcoded, but the code reads TASKNOTES_API_KEY from the environment. A community skill handling API tokens is security-sensitive.","verdict":"confirmed","severity":"high","confidence":0.78},{"id":"env_access:scripts/tasks.py:44:generic-api-secret-keys","reason":"The conditional shows API_KEY is used in the request flow when present. This confirms runtime credential handling, although the value is user supplied.","verdict":"confirmed","severity":"high","confidence":0.74},{"id":"env_access:scripts/tasks.py:45:generic-api-secret-keys","reason":"The API key is placed into an Authorization bearer header for HTTP requests. If the endpoint is misconfigured, the token could be exposed.","verdict":"confirmed","severity":"high","confidence":0.82},{"id":"sensitive:scripts/tasks.py:32:environment-file-access","reason":"The comment describes loading .env from the vault root, and the following code performs that load. A vault-root environment file may contain unrelated secrets.","verdict":"confirmed","severity":"high","confidence":0.82},{"id":"sensitive:scripts/tasks.py:35:environment-file-access","reason":"load_dotenv(VAULT_ROOT / \".env\") reads an environment file outside the skill directory. This is sensitive file access in a community skill.","verdict":"confirmed","severity":"high","confidence":0.93},{"id":"blocker:scripts/tasks.py:169:system-reconnaissance","reason":"urllib.parse.quote URL-encodes a user supplied task id before an API request. It is input sanitization, not system reconnaissance.","verdict":"false_positive","confidence":0.97},{"id":"blocker:scripts/tasks.py:205:system-reconnaissance","reason":"urllib.parse.quote URL-encodes the task id for DELETE /tasks/{id}. It does not inspect the system or gather host information.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","reason":"The backticks describe a .env file path in markdown. There is no shell execution on this line.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:SKILL.md:19:ruby-shell-backtick-execution","reason":"The fenced block contains .env key-value examples, not commands to execute. It includes a placeholder token value only.","verdict":"false_positive","confidence":0.93},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"This is a closing markdown fence. It is not executable code or a shell command.","verdict":"false_positive","confidence":0.95},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","reason":"The line documents when a .env file is unnecessary. It does not ask the agent to run a command.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","reason":"The bash block documents uv run scripts/tasks.py commands that agents may execute, including create, update, and delete. The commands are local and purposeful, but external command execution is real.","verdict":"confirmed","severity":"medium","confidence":0.87},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","reason":"This finding points to the end of a markdown command block and nearby prose. The line itself does not introduce a separate executable command.","verdict":"false_positive","confidence":0.91},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","reason":"The backticks wrap the word options as a command name in prose. It is documentation text, not shell execution.","verdict":"false_positive","confidence":0.92},{"id":"external_commands:SKILL.md:62:ruby-shell-backtick-execution","reason":"The fenced bash example runs uv run scripts/tasks.py options --table. This is local command execution for discovery of configured TaskNotes values.","verdict":"confirmed","severity":"medium","confidence":0.83},{"id":"external_commands:SKILL.md:64:ruby-shell-backtick-execution","reason":"This is a closing markdown fence followed by field documentation. It does not contain an executable shell command.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:SKILL.md:67:ruby-shell-backtick-execution","reason":"Backticks mark the projects field name and an example array. This is markdown formatting, not command execution.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:68:ruby-shell-backtick-execution","reason":"Backticks mark the contexts field name and example values. There is no shell command.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","reason":"Backticks mark the due field name. This is task property documentation, not execution.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:70:ruby-shell-backtick-execution","reason":"Backticks mark the scheduled field name. The line documents a date format, not a command.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","reason":"Backticks mark the timeEstimate field name. No shell or subprocess behavior is present.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:72:ruby-shell-backtick-execution","reason":"Backticks mark the tags field name. This is markdown formatting only.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:73:ruby-shell-backtick-execution","reason":"Backticks mark the details field name. The text describes task content, not external command execution.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","reason":"Backticks wrap a localhost URL. This is API documentation and not Ruby or shell execution.","verdict":"false_positive","confidence":0.95},{"id":"external_commands:SKILL.md:90:ruby-shell-backtick-execution","reason":"Backticks mark the status query parameter. This is API documentation, not a command.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","reason":"Backticks mark the project query parameter. There is no executable command on this line.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:92:ruby-shell-backtick-execution","reason":"Backticks mark the priority query parameter. This is not shell execution.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","reason":"Backticks mark the tag query parameter. The line is API reference text only.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:94:ruby-shell-backtick-execution","reason":"Backticks mark the overdue query parameter. No command execution is described.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","reason":"Backticks mark the sort query parameter. This is documentation, not executable code.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:96:ruby-shell-backtick-execution","reason":"Backticks mark the limit query parameter. There is no shell command.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:97:ruby-shell-backtick-execution","reason":"Backticks mark the offset query parameter. This is markdown formatting only.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:109:ruby-shell-backtick-execution","reason":"The workflow bash block instructs running local CLI commands that list, create, and update TaskNotes tasks. This confirms intended external command use with mutating effects.","verdict":"confirmed","severity":"medium","confidence":0.88},{"id":"network:SKILL.md:77:hardcoded-url","reason":"The skill documents http://localhost:8080/api as its base endpoint. It is local rather than external, but it confirms dependence on a plaintext local HTTP API.","verdict":"confirmed","severity":"low","confidence":0.8},{"id":"env_access:SKILL.md:21:generic-api-secret-keys","reason":"TASKNOTES_API_KEY=your_token_here is a placeholder in documentation, not an embedded real secret. No credential value is exposed in the skill file.","verdict":"false_positive","confidence":0.96},{"id":"sensitive:SKILL.md:18:environment-file-access","reason":"The documentation instructs users to keep TaskNotes API configuration in a vault-root .env file. This is sensitive configuration guidance, though the actual file read is in scripts/tasks.py.","verdict":"confirmed","severity":"high","confidence":0.72},{"id":"sensitive:SKILL.md:23:environment-file-access","reason":"This line says a .env file is not needed when no auth token is set. It does not access a file or disclose a secret.","verdict":"false_positive","confidence":0.9},{"id":"blocker:SKILL.md:103:network-reconnaissance","reason":"The phrase show in-progress tasks describes filtering tasks by status. It is not network reconnaissance.","verdict":"false_positive","confidence":0.97},{"id":"blocker:SKILL.md:111:network-reconnaissance","reason":"The command lists tasks with status in-progress. It queries the TaskNotes API and does not scan networks or discover hosts.","verdict":"false_positive","confidence":0.96}],"semantic_findings":[{"title":"Unvalidated API Port Can Redirect Authenticated Requests","severity":"high","locations":[{"file":"scripts/tasks.py","line_end":39,"line_start":37},{"file":"scripts/tasks.py","line_end":45,"line_start":42},{"file":"scripts/tasks.py","line_end":54,"line_start":53}],"confidence":0.76,"description":"TASKNOTES_API_PORT is inserted into BASE_URL without numeric validation, and TASKNOTES_API_KEY is sent as a bearer header. A crafted port value could change URL parsing and send task data or the token away from localhost.","confidence_reasoning":"The code directly interpolates API_PORT into an HTTP URL and sends headers through requests. Exploitation requires malicious environment or config control, so confidence is high but not absolute."},{"title":"Destructive Task Deletion Without Confirmation","severity":"medium","locations":[{"file":"SKILL.md","line_end":50,"line_start":49},{"file":"scripts/tasks.py","line_end":206,"line_start":203}],"confidence":0.92,"description":"The CLI exposes a delete command that calls DELETE /tasks/{id} without an in-script confirmation, dry-run, or soft-delete safeguard. A mistaken task path can remove a TaskNotes task from the vault.","confidence_reasoning":"The documented delete command maps directly to a DELETE API request in code. No confirmation or recovery safeguard is visible in the cited lines."}],"subject_marketplace_commit_sha":null,"subject_content_hash":null,"subject_tree_hash":null,"subject_plugin_path":null,"audit_payload_hash":null,"confirmed_risk_level":null,"scanner_version":null,"policy_version":null,"subject":{"marketplaceCommitSha":null,"contentHash":null,"treeHash":null,"pluginPath":null,"auditPayloadHash":null},"scannerVersion":null,"policyVersion":null},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"not_attestable","url":null,"status":null,"reason":"confirmed_risk_level does not match the canonical trust resolver"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"high","confirmedFindingCount":5,"capabilityReviewCount":25,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"confirmation_required","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"not_attestable","verificationState":"not_verified"},"isLatest":false}}