Website: Reduce Android Management API usage#49065
Conversation
…d proxy endpoints, add exit that is returned when a 403 response is returned to the proxy
There was a problem hiding this comment.
Pull request overview
This PR reduces Android Management API usage in the fleetdm.com Android proxy by removing the per-request “is this enterprise still managed?” check (which triggers ListEnterprises) and instead relying on Android Management API responses to determine access.
Changes:
- Removed calls to
sails.helpers.androidProxy.getIsEnterpriseManagedByFleet(...)from multiple Android proxy controllers. - Added a new
enterpriseNotAccessibleexit and intercept mapping so Android Management API403responses return anotFound-typed response to Fleet servers.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| website/api/controllers/android-proxy/create-android-enrollment-token.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/create-enterprise-webapp.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/delete-android-device.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/get-android-device.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/get-android-devices.js | Adds enterpriseNotAccessible exit and maps AMAPI 403 accordingly. |
| website/api/controllers/android-proxy/get-enterprise-applications.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/issue-command-on-android-device.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/modify-android-device.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/modify-android-policies.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
| website/api/controllers/android-proxy/modify-enterprise-app-policy.js | Drops enterprise-managed verification call; maps AMAPI 403 to enterpriseNotAccessible. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
WalkthroughThis change updates ten Android proxy controllers (create-android-enrollment-token, create-enterprise-webapp, delete-android-device, get-android-device, get-android-devices, get-enterprise-applications, issue-command-on-android-device, modify-android-device, modify-android-policies, modify-enterprise-app-policy) in the website API. Each controller adds a new Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@website/api/controllers/android-proxy/create-android-enrollment-token.js`:
- Around line 78-80: Update the Android proxy error mapping so deleted
enterprises returning 404 are treated the same as 403 and converted to
enterpriseNotAccessible instead of falling through to a generic 500. In
createAndroidEnrollmentToken’s intercept handler, expand the status interception
to include 404, and apply the same response mapping pattern used by the other
Android proxy controllers in this cohort so enterpriseNotAccessible is returned
consistently.
In `@website/api/controllers/android-proxy/get-enterprise-applications.js`:
- Around line 82-84: The 403 handling in get-enterprise-applications should not
always map to enterpriseNotAccessible; applications.get can fail for scope,
API-enabled, or permission reasons as well. Update the intercept logic in this
controller to inspect the AMAPI error body/reason before deciding whether to
return the enterpriseNotAccessible response, and only use that fallback for the
specific not-authorized case while letting other 403s surface as real
proxy/config errors.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7ace5379-610f-4283-a101-6dec7e27aa0e
📒 Files selected for processing (10)
website/api/controllers/android-proxy/create-android-enrollment-token.jswebsite/api/controllers/android-proxy/create-enterprise-webapp.jswebsite/api/controllers/android-proxy/delete-android-device.jswebsite/api/controllers/android-proxy/get-android-device.jswebsite/api/controllers/android-proxy/get-android-devices.jswebsite/api/controllers/android-proxy/get-enterprise-applications.jswebsite/api/controllers/android-proxy/issue-command-on-android-device.jswebsite/api/controllers/android-proxy/modify-android-device.jswebsite/api/controllers/android-proxy/modify-android-policies.jswebsite/api/controllers/android-proxy/modify-enterprise-app-policy.js
| }).intercept({status: 403}, ()=>{ | ||
| // If the Android management API returns a 403 response, return a enterpriseNotAccessible (notFound) response to the Fleet server. | ||
| return {'enterpriseNotAccessible': 'Fleet is not authorized to manage this Android enterprise.'}; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Google Android Management API enterprises.enrollmentTokens.create HTTP status 403 vs 404 when service account not authorized or enterprise deleted
💡 Result:
When interacting with the Google Android Management API, the HTTP 403 and 404 status codes indicate fundamentally different issues [1][2]. HTTP 403 Forbidden A 403 error signifies an authorization or permission problem [2]. It means the request was understood by the server, but the caller (service account) does not have the necessary permissions to perform the requested action, or the project/enterprise configuration restricts access [2][3]. - Common causes: The service account lacks the required IAM role, such as the Android Management User (roles/androidmanagement.user) role, which contains the androidmanagement.enterprises.manage permission [3][4]. It may also occur if the API is not enabled for the project [3]. HTTP 404 Not Found A 404 error signifies that the requested resource does not exist [1]. In the context of the Android Management API, it indicates that the specific object identified in the API path (e.g., the enterprise or enrollment token) could not be located [1][5]. - Common causes: If an enterprise has been deleted, any attempt to access its resources—such as calling enterprises.enrollmentTokens.create for an enterprise ID that no longer exists—will return a 404 error [1][6]. This is because the server can no longer find the parent resource required to fulfill the request [1]. In summary: 403 means you do not have permission to do what you are asking, while 404 means the entity you are trying to act upon is missing or has been deleted [1][2].
Citations:
- 1: https://community.omnissa.com/forums/topic/72322-error-404-android-management-api-connection-failure-public-account/
- 2: https://stackoverflow.com/questions/72857968/authorization-error-403-access-denied-in-android-management-api-w-o-using-googl
- 3: https://stackoverflow.com/questions/78316649/how-can-i-assign-roles-for-third-party-users-in-android-management-api-on-google
- 4: https://gcp.permissions.cloud/iam/androidmanagement
- 5: https://developers.google.com/android/management/reference/rest/v1/enterprises.devices/delete
- 6: https://developers.google.com/android/management/reference/rest/v1/enterprises/delete
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the target file and nearby status handling.
sed -n '1,220p' website/api/controllers/android-proxy/create-android-enrollment-token.js
echo
echo "---- cohort search ----"
rg -n "getIsEnterpriseManagedByFleet|intercept\\(\\{status: 403\\}|enterpriseNotAccessible" website/api/controllers/android-proxyRepository: fleetdm/fleet
Length of output: 11625
🌐 Web query:
Android Management API enrollmentTokens.create 403 404 enterprise deleted revoked access documentation
💡 Result:
When encountering 403 or 404 errors with the Android Management API's enterprises.enrollmentTokens.create method, the issues typically stem from authorization, resource state, or invalid parent paths [1][2]. 403 Forbidden Errors A 403 status code indicates an authorization or access denial. Common causes include: - Insufficient Permissions: The service account or credentials used do not have the required IAM roles to manage the specified enterprise [2]. - Deleted or Revoked Enterprise: If the enterprise associated with the request has been deleted or its access has been revoked, the API will reject calls made on its behalf [3]. - Invalid Scope: Ensure the request is authorized with the correct OAuth 2.0 scopes necessary for Android Management API operations. 404 Not Found Errors A 404 status code indicates that the requested resource, typically the parent enterprise, does not exist or is inaccessible [2]. Causes include: - Incorrect Parent Path: The parent parameter must be correctly formatted as enterprises/{enterpriseId} [1][4]. If the {enterpriseId} is mistyped, invalid, or does not exist, the API returns a 404. - Deleted Enterprise: If the enterprise itself was deleted, any attempts to interact with its resources (like creating enrollment tokens) will fail with a 404 [3]. - Resource Lifecycle: Once an enrollment token is explicitly deleted via enterprises.enrollmentTokens.delete, it is invalidated and no longer exists [5][4]. Attempting to access or perform operations on a deleted token will result in a 404 [4]. To troubleshoot, verify that your {enterpriseId} is correct, ensure your service account has proper IAM permissions for that specific enterprise, and confirm that the enterprise has not been deleted or suspended [1][2][4]. You can list active enterprises or tokens to verify their current state using the list methods [3][4].
Citations:
- 1: https://developers.google.com/android/management/reference/rest/v1/enterprises.enrollmentTokens/create
- 2: https://stackoverflow.com/questions/78292452/troubleshooting-404-error-in-qr-code-generation-for-android-management-api-enrol
- 3: https://developers.google.com/android/management/reference/rest/v1/enterprises.enrollmentTokens
- 4: https://developers.google.com/android/management/reference/rest/v1/enterprises.enrollmentTokens/get
- 5: https://developers.google.com/android/management/reference/rest/v1/enterprises.enrollmentTokens/delete
Handle 404 as enterpriseNotAccessible too
Deleted Android enterprises can return 404, so a 403-only intercept still sends that case to the generic error path and surfaces a 500. Map 404 here as well; the same pattern applies to the other Android proxy controllers in this cohort.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@website/api/controllers/android-proxy/create-android-enrollment-token.js`
around lines 78 - 80, Update the Android proxy error mapping so deleted
enterprises returning 404 are treated the same as 403 and converted to
enterpriseNotAccessible instead of falling through to a generic 500. In
createAndroidEnrollmentToken’s intercept handler, expand the status interception
to include 404, and apply the same response mapping pattern used by the other
Android proxy controllers in this cohort so enterpriseNotAccessible is returned
consistently.
| }).intercept({status: 403}, ()=>{ | ||
| // If the Android management API returns a 403 response, return a enterpriseNotAccessible (notFound) response to the Fleet server. | ||
| return {'enterpriseNotAccessible': 'Fleet is not authorized to manage this Android enterprise.'}; |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
git ls-files website/api/controllers/android-proxy/get-enterprise-applications.js && sed -n '1,180p' website/api/controllers/android-proxy/get-enterprise-applications.jsRepository: fleetdm/fleet
Length of output: 4616
🏁 Script executed:
rg -n "intercept\\(\\{status: 403\\}|enterpriseNotAccessible|androidmanagement" website/api/controllers website/api/helpers -g '!**/node_modules/**'Repository: fleetdm/fleet
Length of output: 15669
🌐 Web query:
Android Management API applications.get 403 insufficient scope permission API disabled error reason documentation
💡 Result:
When encountering a 403 error while calling the Android Management API enterprises.applications.get method, the error generally stems from one of two distinct configuration issues [1][2][3]. 1. Insufficient Authentication Scopes The enterprises.applications.get method requires the specific OAuth scope https://www.googleapis.com/auth/androidmanagement [4][5]. If your request uses a different or less privileged scope (such as a generic Google Cloud scope), the API will return a 403 error with a message indicating "insufficient authentication scopes" [1][3]. Ensure your OAuth 2.0 flow or service account configuration includes this exact string [5][1]. 2. API Disabled or Not Configured If the Android Management API is not enabled in the Google Cloud project associated with your credentials, or if the service is disabled, the request will fail [2][3]. The API error message often specifies that the API has not been used in the project before or is disabled [2][3]. You can resolve this by visiting the Google Cloud Console for your project, navigating to the APIs & Services dashboard, and ensuring the "Android Management API" is explicitly enabled [2][3]. Other common causes for 403 errors in the Android Management API include: - Permission Denied: Even with the correct scope and enabled API, your credentials may lack the necessary IAM role (e.g., roles/androidmanagement.user) to manage the specific enterprise resource [6]. - Unauthorized Enterprise Access: The service account or user account must be properly associated with the enterprise [6]. If the caller is not authorized to manage that specific enterprise, you will receive a "Caller is not authorized to manage enterprise" 403 error [6]. To troubleshoot, verify your project's API settings in the Google Cloud Console, confirm your service account has the required androidmanagement IAM roles, and ensure your access token was requested with the correct androidmanagement scope [4][5][6].
Citations:
- 1: Request had insufficient authentication scopes googleapis/google-api-python-client#915
- 2: Log error, but skip over scope, disabled APIs GoogleCloudPlatform/terraformer#627
- 3: https://stackoverflow.com/questions/76328118/how-to-authenticate-google-analytics-api-with-user-credentials-not-service-accou
- 4: https://developers.google.com/android/management/reference/rest/v1/enterprises.applications/get
- 5: https://byron.github.io/google-apis-rs/google_androidmanagement1_cli/enterprises_applications-get/
- 6: https://stackoverflow.com/questions/66043205/android-management-api-caller-is-not-authorized-to-manage-enterprise
Don't collapse every AMAPI 403 into enterpriseNotAccessible. applications.get can also return 403 for scope, API-enabled, or permission issues, so this turns real proxy/config failures into a generic 404. Inspect the error reason/body before mapping it here.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@website/api/controllers/android-proxy/get-enterprise-applications.js` around
lines 82 - 84, The 403 handling in get-enterprise-applications should not always
map to enterpriseNotAccessible; applications.get can fail for scope,
API-enabled, or permission reasons as well. Update the intercept logic in this
controller to inspect the AMAPI error body/reason before deciding whether to
return the enterpriseNotAccessible response, and only use that fallback for the
specific not-authorized case while letting other 403s surface as real
proxy/config errors.
Related to: #41908
Changes:
create-android-enrollment-token,create-enterprise-webapp,delete-android-device,get-android-device,get-android-devices,get-enterprise-applications,issue-command-on-android-device,modify-android-device,modify-android-policies, andmodify-enterprise-app-policy) to send requests to the Android Management API without verifying that an enterprise is still managed by Fleet with the getIsEnterpriseManagedByFleet helper, and to return aenterpriseNotAccessible(notFound) response to Fleet servers if the Android management API returns a 403 response.Summary by CodeRabbit