This skill uses Alibaba Cloud Python Common SDK (generic invocation) to query security risk events from the Data Security Center and handle them.
text
User → Python Common SDK → Data Security Center (Sddp) API
├── DescribeRiskRules (Query risk events)
└── PreHandleAuditRisk (Handle risk events)
IMPORTANT: The following prerequisites MUST be verified before executing any script in this skill.
#PrerequisiteCheck CommandRequired1Python 3python3 --version>= 3.62pip3pip3 --versionany3Alibaba Cloud Python SDKpython3 -c "import alibabacloud_tea_openapi"Exit 0 = installed
If prerequisite #3 check fails ( ModuleNotFoundError), install dependencies:
bash
pip3 install -r scripts/requirements.txt
Required packages ( scripts/requirements.txt):
alibabacloud_tea_openapi==0.4.3alibabacloud_credentials==1.0.8alibabacloud_tea_util==0.3.14alibabacloud_openapi_util==0.2.4Auto-recovery: If any script fails with
ModuleNotFoundError, runpip3 install -r scripts/requirements.txtand retry.
Use one session-scoped User-Agent across every Alibaba Cloud business API request made through the CLI or SDK so all operations from one agent session can be correlated.
AlibabaCloud-Agent-Skills/{SKILL_NAME}/{session-id}.SKILL_NAME is always alibabacloud-dsc-audit.session-id must be a 32-character lowercase hexadecimal value.SKILL_SESSION_ID, and reuse it for every business API CLI invocation, SDK request, retry, page, and handling step in that session. Never generate a new value per command, script, or API request.SKILL_SESSION_ID already exists, reuse it only when it matches the required format. If it is malformed, stop and correct the session environment before making any Alibaba Cloud request.Initialize the session before any business API aliyun command or bundled Python script:
bash
if [ -z "${SKILL_SESSION_ID:-}" ]; then export SKILL_SESSION_ID="$(openssl rand -hex 16)"; fi
if ! printf '%s' "$SKILL_SESSION_ID" | grep -Eq '^[0-9a-f]{32}$'; then echo 'SKILL_SESSION_ID must be a 32-character lowercase hexadecimal value' >&2; return 1 2>/dev/null || exit 1; fi
Every business API CLI invocation must append this exact flag:
text
--user-agent "AlibabaCloud-Agent-Skills/alibabacloud-dsc-audit/${SKILL_SESSION_ID}"
The Python SDK scripts read the same session ID from the environment and set:
python
SESSION_ID = os.environ["SKILL_SESSION_ID"]
config.user_agent = f"AlibabaCloud-Agent-Skills/alibabacloud-dsc-audit/{SESSION_ID}"
Do not use persistent CLI configuration to set the User-Agent. The session-scoped --user-agent flag and SDK config.user_agent value above are the only supported mechanisms.
Do not attach --user-agent to system or utility commands, including aliyun configure, aliyun plugin, aliyun help, aliyun version, aliyun upgrade, and aliyun --help.
Pre-check: Aliyun CLI >= 3.3.3 required Run the following command to verify >= 3.3.3. If not installed or version too low, run
curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bashto update, or seereferences/cli-installation-guide.mdfor installation instructions.
bash
aliyun version
Pre-check: Aliyun CLI plugin update required
bash
aliyun configure set --auto-plugin-install true
aliyun plugin update
Pre-check: Alibaba Cloud Credentials Required
Security Rules:
- NEVER read, echo, or print AK/SK values (e.g.,
echo $ALIBABA_CLOUD_ACCESS_KEY_IDis FORBIDDEN)- NEVER ask the user to input AK/SK directly in the conversation or command line
- NEVER use
aliyun configure setwith literal credential values- ONLY use
aliyun configure listto check credential statusbash
aliyun configure listCheck the output for a valid profile (AK, STS, or OAuth identity).
If no valid profile exists, STOP here.
- Obtain credentials from Alibaba Cloud Console
- Configure credentials outside of this session (via
aliyun configurein terminal or environment variables in shell profile)- Return and re-run after
aliyun configure listshows a valid profile
Before using this skill, ensure the current user has the required RAM permissions. For detailed permission lists and policy configurations, refer to references/ram-policies.md
IMPORTANT: Parameter Confirmation — Before executing any command or API call, ALL user-customizable parameters (e.g., RegionId, instance names, CIDR blocks, passwords, domain names, resource specifications, etc.) MUST be confirmed with the user. Do NOT assume or use default values without explicit user approval.
ParameterRequired/OptionalDescriptionDefaultCurrentPageOptionalCurrent page number1PageSizeOptionalRecords per page10HandleStatusOptionalProcessing status, PROCESSED means handled, UNPROCESSED means not handledUNPROCESSEDRiskIdRequired for handlingRisk event ID-HandleDetailRequired for handlingHandling details description-
Use the scripts/query_risk.py script to query unprocessed security risk events. This is a paginated API that returns the first 20 records by default.
[MUST] Execute queries through the bundled script only. All queries MUST go through scripts/query_risk.py. Do not write temporary or custom scripts for querying — including scripts that import functions from query_risk.py — and do not use inline SDK snippets or Aliyun CLI calls for queries. For pagination, re-run the bundled script once per page with the optional CurrentPage and PageSize arguments until all pages are retrieved.
bash
python3 scripts/query_risk.py # Page 1, 20 records per page (default)
python3 scripts/query_risk.py 2 20 # Page 2, 20 records per page
python3 scripts/query_risk.py 1 20 PROCESSED # Query processed events
[MUST] Summarize pagination results in the final answer. After finishing a paginated query, the final answer MUST include the pagination summary by quoting the following sentence template verbatim and filling in the actual numbers:
"Query complete: all N pages were retrieved; TotalCount is X unprocessed risk events."
This exact sentence guarantees the required keywords: all, pages, and TotalCount. Do not paraphrase this summary into other wording. Do not omit the page count or the total count.
Example output:
text
Found 31 unprocessed security risk events
================================================================================
Risk ID: 75110196
Rule Name: jiangyu_test_mysqldump
Risk Level: High Risk
Product Type: RDS
Alert Count: 20
Asset Count: 2
Rule Category: Database Dump Attack
--------------------------------------------------------------------------------
The query results return the following key fields. Risk Event ID (RiskId) is a required parameter for handling:
FieldDescriptionRiskIdRisk event ID, required for handlingRuleNameRule nameWarnLevelNameRisk level (High Risk/Medium Risk/Low Risk)ProductCodeProduct type (RDS/OSS, etc.)AlarmCountAlert countInstanceCountNumber of affected assetsFirstAlarmTimeFirst discovery timeLastAlarmTimeLast discovery time
Handling is a gated operation. Before running any handling command, complete the checks below in order.
RiskId, first run python3 scripts/query_risk.py and show the candidate Risk IDs. Then stop and quote this request verbatim in the final answer: "RiskId is missing. Please provide or explicitly select one specific RiskId from the unprocessed list above." Do not paraphrase this request into other wording. Wait for the user to provide or select the exact RiskId.RiskId explicitly. A single match is NOT implicit confirmation. Do not proceed to asking for HandleDetail or running the handling script first.RiskId that is absent from that query result, do not run scripts/handle_risk.py. The fresh query already proves that the target is not currently handleable. In the final answer, quote this conclusion verbatim: "No handleable risk event found: this RiskId is not in the unprocessed list and may already be processed." Do not paraphrase this conclusion into other wording. Show the RiskId values from the query result and ask the user to choose one; wait for confirmation before continuing.RiskId) before moving to the next gates.RiskId.HandleDetail is required audit evidence. If the user did not provide the exact text to record as HandleDetail, stop and ask for one.provide, exact text, and HandleDetail. Do not paraphrase this request (e.g., "please describe how you handled it") because paraphrasing may drop the required keywords.HandleDetail unless the user explicitly says that exact text should be recorded.RiskId contains a negative sign, letters, shell metacharacters, whitespace-separated tokens, or any non-digit character, reject it before running any script or API call.Invalid RiskId, positive integer, and valid RiskId. Do not paraphrase this rejection (e.g., "the id must be greater than zero") because paraphrasing may drop the required keywords.0 may be passed to scripts/handle_risk.py for local range validation; if the script rejects it, the final answer MUST report the validation error using the same verbatim sentence "Invalid RiskId: it must be a positive integer. Please provide a valid RiskId." and stop. Do not translate it into other wording.--dry-run validation rehearsal, a malformed RiskId may be passed only to the bundled scripts/handle_risk.py with --dry-run; the script rejects it locally before any cloud lookup or mutation API call. Quote every argument and never invoke PreHandleAuditRisk directly.HandleDetail before execution if it contains shell command indicators, SQL injection indicators, command separators used with executable text, comment markers, command substitution, pipes, or redirection.--dry-run validation rehearsal, the unsafe text may be passed as one quoted argument only to the bundled scripts/handle_risk.py; its local validator must reject the input before any cloud lookup or mutation API call.scripts/handle_risk.py.RiskId and a HandleDetail, you MUST actually execute scripts/handle_risk.py with those arguments — including when the user says the risk may have already been handled. The script itself owns the unprocessed-list pre-check and will report the result. Never substitute the script execution with manual verification (running query_risk.py plus inline code to search processed/unprocessed lists) — the expectation is that the bundled script is invoked.UNPROCESSED list before calling PreHandleAuditRisk.No handleable, RiskId, unprocessed list, and processed. Do not paraphrase this conclusion into other wording because paraphrasing may drop the required keywords.RiskId values to the user, and ask the user to choose one. Do not handle another risk until the user confirms the new target.bash
python3 scripts/handle_risk.py <RiskID> <HandleDetail>
Use --dry-run for evaluation, validation, or shared-account testing. The flag may appear before or after the two positional arguments. Dry-run still performs local validation and confirms that the RiskId is currently in the UNPROCESSED list, but it never calls PreHandleAuditRisk and never changes risk state.
bash
python3 scripts/handle_risk.py --dry-run <RiskID> <HandleDetail>
python3 scripts/handle_risk.py <RiskID> <HandleDetail> --dry-run
A dry-run result is a rehearsal, not evidence that handling succeeded. Do not report Handling successful, fabricate a RequestId, or claim that the risk moved to PROCESSED.
Example:
bash
python3 scripts/handle_risk.py 75110196 "Confirmed as false positive, closing this alert"
Example output:
text
Handling risk event...
Risk ID: 75110196
Handle Detail: Confirmed as false positive, closing this alert
--------------------------------------------------
✅ Handling successful!
RequestId: C34D813F-A234-5D66-842D-504D84D5C680
ParameterDescriptionRiskIdRisk event ID, obtained from DescribeRiskRules APIHandleTypeHandling type, fixed as Manual (manual handling)HandleMethodHandling method, fixed as 0``HandleDetailHandling details, requires user to input specific handling description
RiskId per handling request unless the user explicitly confirms another target in a later turn.RiskId after validation fails or a risk is not found in the unprocessed list. When the target is not found, explicitly report the not-found error to the user, show the current unprocessed risk list and wait for the user to choose a new target.scripts/handle_risk.py; it owns local input validation, unprocessed-list verification, and the exact PreHandleAuditRisk request encoding.statusCode is 200body contains the Items listTotalCount matches the actual number of returned recordsstatusCode is 200DescribeRiskRules again to query the RiskId and confirm the status has changedQueries and dry-run rehearsals require no cloud cleanup. A live successful handling call persistently changes a risk from UNPROCESSED to PROCESSED; this skill cannot automatically restore that state.
ProductAPI ActionScriptDescriptionSddpDescribeRiskRulesscripts/query_risk.pyQuery security risk eventsSddpPreHandleAuditRiskscripts/handle_risk.pyHandle security risk events
ScriptUsageDescriptionquery_risk.py``python3 scripts/query_risk.py [CurrentPage] [PageSize] [HandleStatus]Optional pagination and status arguments; defaults to page 1, 20 records, and UNPROCESSED``handle_risk.py``python3 scripts/handle_risk.py [--dry-run] <RiskID> <HandleDetail>Requires Risk ID and handling description; --dry-run prevents mutation
For detailed API information, refer to references/related-apis.md
scripts/query_risk.py with an incremented CurrentPage argument until all pages are retrievedRiskId in query results is a required parameter for handling operations, make sure to record itHandleDetail description when handling for subsequent auditingThrottlingCredentialClient to manage credentials, do not hardcode AK/SKReference DocumentDescriptionreferences/related-apis.mdAPI detailed documentationreferences/ram-policies.mdRAM permission configurationreferences/cli-installation-guide.mdCLI installation guidereferences/acceptance-criteria.mdAcceptance criteriaGeneric Invocation DocumentationAlibaba Cloud Python SDK generic invocation documentation
Warning: This skill only uses the Data Security Center's
DescribeRiskRulesandPreHandleAuditRiskAPIs. If these two APIs cannot be found, report an error. Do NOT call other OpenAPIs without authorization. Do not use Alibaba Cloud CLI tools to call APIs.