Skip to content
Report library
Purpose / Development

Azure Cloud Migrate Skill Security Audit

What the author says it does (original text)

Assess and migrate cross-cloud workloads to Azure with reports and code conversion. Supports Lambda→Functions, Beanstalk/Heroku/App Engine→App Service, Fargate/Kubernetes/Cloud Run/Spring Boot→Container Apps. WHEN: migrate Lambda to Functions, AWS to Azure, migrate Beanstalk, migrate Heroku, migrate App Engine, Cloud Run migration, Fargate to ACA, ECS/Kubernetes/GKE/EKS to Container Apps, Spring B

Independent security check

Do not install or run it yet

Files checked
31
Risks found
4
Could it run dangerous commands?Looks for programs run straight after downloading, remote control of your computer, and hidden commands.No risks found
Could it expose your files or keys?Looks for uploads of files containing passwords or keys, and keys written directly in the code.Risks found: 2
High risk

The Kubernetes export script writes Secret objects to a local file

Source references: 1
What we found

The export command explicitly includes `secret` and redirects the complete YAML to an output file. Kubernetes Secret values are commonly Base64-encoded, not encrypted.

Why this matters

Anyone able to read the directory, backups, build artifacts, or attached logs may obtain database passwords, tokens, or certificate material.

The active export script serializes Kubernetes `secret` objects with other resources into local `all-resources.yaml`. When run, Secret data is generally Base64-encoded, not encrypted; credentials could leak if the directory is committed, backed up, or readable by others. The user can require secrets to be excluded by default, exporting only names/references, with restricted output permissions and retention.

references/services/container-apps/deployment-guide.md:19In the instructionsOpen original file
set -euo pipefailNAMESPACE="${K8S_NAMESPACE:-<namespace>}"OUTPUT_DIR="${OUTPUT_DIR:-k8s-export}"mkdir -p "$OUTPUT_DIR"kubectl get deploy,svc,ingress,configmap,secret -n "$NAMESPACE" -o yaml > "$OUTPUT_DIR/all-resources.yaml"for deploy in $(kubectl get deploy -n "$NAMESPACE" -o jsonpath='{.items[*].metadata.name}'); do  kubectl get deployment "$deploy" -n "$NAMESPACE" -o yaml > "$OUTPUT_DIR/deploy-${deploy}.yaml"done
Medium risk

Some guides place secrets and Log Analytics shared keys in command arguments

Source references: 3
What we found

Secrets produced by command substitution or stored in variables are expanded into process arguments for `az ... --value` or `--logs-workspace-key`. Although they are not written to an ordinary file, process monitoring, verbose CI logs, shell tracing, or error collection can still capture them.

Why this matters

A person able to observe command lines or pipeline diagnostics may obtain GCP, Kubernetes, or Azure monitoring credentials and use the associated services.

These are executable deployment examples. The Cloud Run example expands a secret fetched from GCP into a `--value` argument, while the same guide retrieves the Log Analytics primary shared key and passes it as a command argument. Process inspection, shell tracing, verbose CI logs, or error capture could record these values; “without writing them to disk” does not prevent that. Users can require protected-file/stdin handling, disabled tracing, and keyless logging configuration.

references/services/container-apps/cloudrun-deployment-guide.md:114In the instructionsOpen original file
# Migrate secrets without writing them to diskaz keyvault secret set --vault-name "$KEY_VAULT" --name <secret-name> \  --value "$(gcloud secrets versions access latest --secret=<secret-id> --project="$GCP_PROJECT")"
Show 2 other places
references/services/container-apps/deployment-guide.md:89In the instructionsOpen original file
# Create Key Vault and migrate secrets (pipe directly — no temp file)az keyvault create --name myapp-kv --resource-group myapp-rg --location eastusaz keyvault secret set --vault-name myapp-kv --name password --value "$(kubectl get secret mysecret -n <namespace> -o jsonpath='{.data.password}' | base64 -d)"
references/services/container-apps/cloudrun-deployment-guide.md:54In the instructionsOpen original file
az monitor log-analytics workspace create -g "$RG" -n "${RG}-logs" -l "$LOCATION"LOG_ID=$(az monitor log-analytics workspace show -g "$RG" -n "${RG}-logs" --query customerId -o tsv)LOG_KEY=$(az monitor log-analytics workspace get-shared-keys -g "$RG" -n "${RG}-logs" --query primarySharedKey -o tsv)az containerapp env create -n "${RG}-env" -g "$RG" -l "$LOCATION" \  --logs-workspace-id "$LOG_ID" --logs-workspace-key "$LOG_KEY"```
Could it delete files or keep running?Looks for broad file deletion, disk overwrites, and programs set to start automatically.No risks found
Could it bypass safety checks?Looks for skipped website security checks, excessive file access, or actions that skip your approval.Risks found: 2
Medium risk

Migration examples default to external ingress and anonymous HTTP functions

Source references: 4
What we found

Several deployment examples hard-code `--ingress external`, while runtime examples set anonymous authorization. If the agent copies these patterns without preserving the source system's authentication and internal-ingress requirements, the service becomes Internet-accessible.

Why this matters

Unauthenticated parties may reach migrated endpoints, trigger functions, read application responses, or generate resource costs.

Deployment examples explicitly create external ingress, and a Functions example uses anonymous authorization. If an agent applies them to a real migration without preserving the source access controls, the service or function could become internet-accessible. These are examples rather than automatically executed code, and global rules require deployment confirmation, but confirming deployment is not the same as approving public access. Users can require internal ingress and authenticated functions by default, with a separate exposure review.

references/services/container-apps/fargate-deployment-guide.md:162In the instructionsOpen original file
SECRET_URI=$(az keyvault secret show --vault-name "$KEY_VAULT" --name db-password --query id -o tsv)az containerapp create --name <app-name> -g "$RG" --environment "${RG}-env" \  --image "${ACR_NAME}.azurecr.io/<image>:<tag>" --target-port 8080 --ingress external \  --cpu 0.5 --memory 1Gi --min-replicas 1 --max-replicas 10 \  --user-assigned "$IDENTITY_ID" --registry-identity "$IDENTITY_ID" \  --registry-server "${ACR_NAME}.azurecr.io" \  --secrets db-pass=keyvaultref:"${SECRET_URI}",identityref:"${IDENTITY_ID}" \  --env-vars ENV=production DB_PASSWORD=secretref:db-pass```
Show 3 other places
references/services/functions/runtimes/javascript.md:50In the instructionsOpen original file
```javascriptapp.http('httpFunction', {  methods: ['GET', 'POST'],  authLevel: 'anonymous',  handler: async (request, context) => {    const name = request.query.get('name') || (await request.text());
references/services/functions/runtimes/csharp.md:9In the instructionsOpen original file
```csharp[Function("HttpFunction")]public static HttpResponseData Run(    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,    FunctionContext context){
references/services/app-service/global-rules.md:16In the instructionsOpen original file
Always use `ask_user` before:- Selecting Azure subscription- Selecting Azure region/location- Deploying infrastructure- Making breaking changes to existing code- Choosing App Service Plan tier (Free, Basic, Standard, Premium)
Medium risk

The function pattern gives its runtime identity resource-group event-management and Storage Data Owner privileges

Source references: 2
What we found

The “required roles” table recommends granting the same user-assigned managed identity EventGrid EventSubscription Contributor at resource-group scope and Storage Blob Data Owner at storage-account scope. These capabilities exceed ordinary read/write access to application objects.

Why this matters

If the application or runtime identity is compromised, an attacker may delete blobs, alter their access controls, or create and modify event subscriptions in the resource group.

The guide explicitly assigns EventGrid EventSubscription Contributor to the UAMI and lists it at resource-group scope, alongside Storage Blob Data Owner at storage-account scope. If this UAMI is the application's runtime identity, an application compromise could permit management of event subscriptions across the resource group and Blob owner-level actions beyond ordinary object reads/writes. Users can require separate deployment and runtime identities, with container-scoped storage access and narrower roles.

references/services/functions/lambda-to-functions.md:218In the instructionsOpen original file
### Required RBAC Roles for Face Blur Pattern| Role | Scope | Purpose ||------|-------|---------|| Storage Blob Data Owner | Storage Account | Read source blobs, write destination blobs || Storage Queue Data Contributor | Storage Account | Poison-message queue for blob extension || EventGrid EventSubscription Contributor | Resource Group | Create/manage Event Grid subscriptions || Cognitive Services User | Cognitive Services Account | Call Computer Vision API || Monitoring Metrics Publisher | Application Insights | Emit telemetry |
Show 1 other places
references/services/functions/lambda-to-functions.md:185In the instructionsOpen original file
**RBAC requirement**: Assign **EventGrid EventSubscription Contributor** role to the UAMI.
Could it mislead the AI or hide text?Checks the skill instructions for requests to ignore you, influence the report, or hide text in invisible characters.No risks found
Could it change links or payment recipients without asking?Looks for forced referral or payment changes combined with instructions to hide the change.No risks found

Inside this skill

4 instruction sections

The Skill first assesses an existing cloud application, then writes converted code and configuration to a separate Azure output directory in the workspace; its stated rules say not to modify the source directory.

View source
SKILL.md:16In the instructionsOpen original file
1. Follow phases sequentially — do not skip2. Generate assessment before any code migration3. Load the scenario reference and follow its rules4. Use `mcp_azure_mcp_get_azure_bestpractices` and `mcp_azure_mcp_documentation` MCP tools
SKILL.md:40In the instructionsOpen original file
## Output DirectoryAll output goes to `<workspace-root-basename>-azure/` at workspace root, where `<workspace-root-basename>` is the name of the top-level workspace directory itself (NOT a subdirectory within it). Never modify the source directory.

This is not only a reporting tool: the scenario guides contain commands to authenticate to source and target registries, pull and push images, create Azure resources, assign roles, and deploy applications.

View source
references/services/container-apps/fargate-deployment-guide.md:11In the instructionsOpen original file
set -euo pipefailaws ecr get-login-password --region "$AWS_REGION" | \  docker login --username AWS --password-stdin "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"az acr login --name "$ACR_NAME"docker pull "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${IMAGE}"docker tag "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${IMAGE}" "${ACR_NAME}.azurecr.io/${IMAGE}"docker push "${ACR_NAME}.azurecr.io/${IMAGE}"```
references/services/container-apps/fargate-deployment-guide.md:95In the instructionsOpen original file
set -euo pipefailaz keyvault create --name "$KEY_VAULT" -g "$RG" -l "$LOCATION" \  --enable-rbac-authorization trueIDENTITY_ID=$(az identity create -n "${RG}-id" -g "$RG" -l "$LOCATION" --query id -o tsv)PRINCIPAL_ID=$(az identity show --ids "$IDENTITY_ID" --query principalId -o tsv)# Grant Key Vault access — use RBAC (recommended) or access policies# Option A: RBAC (enabled on the vault created above)KV_ID=$(az keyvault show --name "$KEY_VAULT" --query id -o tsv)az role assignment create --assignee "$PRINCIPAL_ID" \  --role "Key Vault Secrets User" --scope "$KV_ID"# Option B: Access policies (if vault uses access policy mode)

The stated policy requires user confirmation before selecting a subscription, region, or service tier and before deployment or destructive operations. Users should treat these confirmations as a security boundary and verify the exact subscription, region, resources, and exposure settings.

View source
references/services/app-service/global-rules.md:7In the instructionsOpen original file
⛔ **NEVER** perform destructive actions without explicit user confirmation via `ask_user`:- Deleting files or directories- Overwriting existing code- Deploying to production environments- Modifying existing Azure resources- Removing source-platform resources
references/services/app-service/global-rules.md:16In the instructionsOpen original file
Always use `ask_user` before:- Selecting Azure subscription- Selecting Azure region/location- Deploying infrastructure- Making breaking changes to existing code- Choosing App Service Plan tier (Free, Basic, Standard, Premium)

After code migration, the workflow hands off to other Azure Skills for infrastructure generation and then chains into validation and deployment, so authorizing deployment may trigger a multi-stage set of cloud-account changes.

View source
references/services/functions/code-migration.md:130In the instructionsOpen original file
After code migration is complete:1. Update `migration-status.md` — mark Code Migration as ✅ Complete2. Invoke **azure-prepare** — pass the assessment report context so it can:   - Use the service mapping as requirements input (skips manual gather-requirements)   - Generate IaC (Bicep/Terraform) for the mapped Azure services   - Create `azure.yaml` and `.azure/preparation-manifest.md`   - Apply security hardening3. azure-prepare will then chain to **azure-validate** → **azure-deploy**
Start here · InstructionsSKILL.md
azure-cloud-migrate
Lines connect the instruction file to its sections, not an observed execution order. Select a section to read the source.

File reference map

References: 40
Files making referencesReferenced content
Lines show actual file references, not execution order. Select a node to highlight its connections and inspect the files and source locations. Dashed lines include files that still need locating.
Files and check records31 files

Coverage and gaps

Content covered in each file

These are the source ranges included in this check, not a guarantee that every issue has been resolved.

  • SKILL.mdFull text included
  • references/services/app-service/app-engine-to-app-service.mdFull text included
  • references/services/app-service/assessment.mdFull text included
  • references/services/app-service/beanstalk-to-app-service.mdFull text included
  • references/services/app-service/code-migration.mdFull text included
  • references/services/app-service/global-rules.mdFull text included
  • references/services/app-service/heroku-to-app-service.mdFull text included
  • references/services/container-apps/cloudrun-to-container-apps.mdFull text included
  • references/services/container-apps/fargate-assessment-guide.mdFull text included
  • references/services/container-apps/fargate-deployment-guide.mdFull text included
  • references/services/container-apps/fargate-to-container-apps.mdFull text included
  • references/services/container-apps/k8s-to-container-apps.mdFull text included
  • references/services/container-apps/spring-apps-to-aca.mdFull text included
  • references/services/functions/assessment.mdFull text included
  • references/services/functions/code-migration.mdFull text included
  • references/services/functions/global-rules.mdFull text included
  • references/services/functions/lambda-to-functions.mdFull text included
  • references/workflow-details.mdFull text included
  • references/services/container-apps/assessment-guide.mdFull text included
  • references/services/container-apps/cloudrun-assessment-guide.mdFull text included
  • references/services/container-apps/cloudrun-deployment-guide.mdFull text included
  • references/services/container-apps/deployment-guide.mdFull text included
  • references/services/container-apps/spring-assessment-guide.mdFull text included
  • references/services/container-apps/spring-dependency-patterns.mdFull text included
  • references/services/container-apps/spring-deployment-guide.mdFull text included
  • references/services/functions/runtimes/csharp.mdFull text included
  • references/services/functions/runtimes/java.mdFull text included
  • references/services/functions/runtimes/javascript.mdFull text included
  • references/services/functions/runtimes/powershell.mdFull text included
  • references/services/functions/runtimes/python.mdFull text included
  • references/services/functions/runtimes/typescript.mdFull text included

This report is for the version above. We read the available code and instructions without running the skill or checking extra packages it installs. This is not a promise of safety: a different version or setup may behave differently.

  • SKILL.mdInstructions
  • references/services/app-service/app-engine-to-app-service.mdSupporting file
  • references/services/app-service/assessment.mdSupporting file
  • references/services/app-service/beanstalk-to-app-service.mdSupporting file
  • references/services/app-service/code-migration.mdSupporting file
  • references/services/app-service/global-rules.mdSupporting file
  • references/services/app-service/heroku-to-app-service.mdSupporting file
  • references/services/container-apps/assessment-guide.mdSupporting file
  • references/services/container-apps/cloudrun-assessment-guide.mdSupporting file
  • references/services/container-apps/cloudrun-deployment-guide.mdSupporting file
  • references/services/container-apps/cloudrun-to-container-apps.mdSupporting file
  • references/services/container-apps/deployment-guide.mdSupporting file
  • references/services/container-apps/fargate-assessment-guide.mdSupporting file
  • references/services/container-apps/fargate-deployment-guide.mdSupporting file
  • references/services/container-apps/fargate-to-container-apps.mdSupporting file
  • references/services/container-apps/k8s-to-container-apps.mdSupporting file
  • references/services/container-apps/spring-apps-to-aca.mdSupporting file
  • references/services/container-apps/spring-assessment-guide.mdSupporting file
  • references/services/container-apps/spring-dependency-patterns.mdSupporting file
  • references/services/container-apps/spring-deployment-guide.mdSupporting file
  • references/services/functions/assessment.mdSupporting file
  • references/services/functions/code-migration.mdSupporting file
  • references/services/functions/global-rules.mdSupporting file
  • references/services/functions/lambda-to-functions.mdSupporting file
  • references/services/functions/runtimes/csharp.mdSupporting file
  • references/services/functions/runtimes/java.mdSupporting file
  • references/services/functions/runtimes/javascript.mdSupporting file
  • references/services/functions/runtimes/powershell.mdSupporting file
  • references/services/functions/runtimes/python.mdSupporting file
  • references/services/functions/runtimes/typescript.mdSupporting file
  • references/workflow-details.mdSupporting file

Operations mentioned in code and instructions

Connect to websites
SKILL.md:23In the instructionsOpen original file
7. **Report progress to user** — During long-running operations (deployments, image pushes), provide resource-level status updates so the user is never left waiting without feedback — see [workflow-details.md](references/workflow-details.md 8. **Audit service discovery in app code** — Kubernetes DNS names (e.g., `http://order-service:3001`) do not resolve in Container Apps. During assessment, scan source code for hardcoded hostnames/ports in HTTP clients and flag them for env-var-driven URL injection
references/services/app-service/app-engine-to-app-service.md:180In the instructionsOpen original file
- [GCP to Azure services comparison](https://learn.microsoft.com/en-us/azure/architecture/gcp-professional/)- [App Service overview](https://learn.microsoft.com/en-us/azure/app-service/overview)
references/services/app-service/app-engine-to-app-service.md:181In the instructionsOpen original file
- [GCP to Azure services comparison](https://learn.microsoft.com/en-us/azure/architecture/gcp-professional/)- [App Service overview](https://learn.microsoft.com/en-us/azure/app-service/overview)- [Cosmos DB migration options](https://learn.microsoft.com/en-us/azure/cosmos-db/migration-choices)
Read keys or account settings
references/services/app-service/beanstalk-to-app-service.md:161In the instructionsOpen original file
| Secrets Manager refs | Key Vault | Secrets with rotation || `.env` file | App Settings + Key Vault | Split by sensitivity |
references/services/app-service/code-migration.md:57In the instructionsOpen original file
> ⚠️ **Port**: App Service injects `PORT` env var. Always bind to `process.env.PORT || 8080`.
references/services/app-service/code-migration.md:64In the instructionsOpen original file
const appInsights = require('applicationinsights');appInsights.setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING)  .setAutoCollectRequests(true)
Run commands
references/services/container-apps/cloudrun-deployment-guide.md:9In the instructionsOpen original file
### Bash
references/services/container-apps/cloudrun-deployment-guide.md:11In the instructionsOpen original file
```bashset -euo pipefail
references/services/container-apps/cloudrun-deployment-guide.md:26In the instructionsOpen original file
### PowerShell
Change files
references/services/container-apps/fargate-deployment-guide.md:113In the instructionsOpen original file
secret_file="$(mktemp)"trap 'rm -f "$secret_file"' EXITaws secretsmanager get-secret-value --secret-id <secret-id> --region <region> \
references/services/container-apps/fargate-deployment-guide.md:118In the instructionsOpen original file
  --file "$secret_file"rm -f "$secret_file"trap - EXIT
references/services/container-apps/spring-deployment-guide.md:102In the instructionsOpen original file
SECRET_FILE=$(mktemp)trap 'shred -u "$SECRET_FILE" 2>/dev/null || rm -f "$SECRET_FILE"' EXITread -s -p "Enter database password: " DB_PASSWORD
Lines read
4,615
File checksum (to compare versions)
95ae05d14c7ca0c3a1a7d4dccbacaab8d3e52ee5ba69241785f0df75abd71242