Tweak manual enroll profile permissions (#50688)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves # # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Restricted access to manual MDM enrollment profiles to global or team administrators and maintainers. * Prevented unauthenticated, roleless, observer, and GitOps users from viewing enrollment profile data. * Updated authorization documentation to reflect the required permissions. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- Restricted the manual MDM enrollment profile endpoint (`GET /api/v1/fleet/enrollment_profiles/manual`) to global and fleet-scoped admins and maintainers.
|
||||
@@ -1192,10 +1192,20 @@ allow {
|
||||
action == write
|
||||
}
|
||||
|
||||
# Any logged in user can read the manual enrollment profile data.
|
||||
# The manual enrollment profile embeds the SCEP challenge, so it is restricted
|
||||
# to the same roles as enroll secrets.
|
||||
|
||||
# Global admins and maintainers can read the manual enrollment profile data.
|
||||
allow {
|
||||
object.type == "mdm_apple_manual_enrollment_profile"
|
||||
not is_null(subject)
|
||||
subject.global_role == [admin, maintainer][_]
|
||||
action == read
|
||||
}
|
||||
|
||||
# Team admins and maintainers can read the manual enrollment profile data.
|
||||
allow {
|
||||
object.type == "mdm_apple_manual_enrollment_profile"
|
||||
team_role(subject, subject.teams[_].id) == [admin, maintainer][_]
|
||||
action == read
|
||||
}
|
||||
|
||||
|
||||
@@ -2611,6 +2611,30 @@ func TestAuthorizeMDMAppleSetupAssistant(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAuthorizeMDMAppleManualEnrollmentProfile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
profile := &fleet.MDMAppleManualEnrollmentProfile{}
|
||||
runTestCases(t, []authTestCase{
|
||||
{user: nil, object: profile, action: read, allow: false},
|
||||
{user: test.UserNoRoles, object: profile, action: read, allow: false},
|
||||
|
||||
{user: test.UserAdmin, object: profile, action: read, allow: true},
|
||||
{user: test.UserMaintainer, object: profile, action: read, allow: true},
|
||||
{user: test.UserObserver, object: profile, action: read, allow: false},
|
||||
{user: test.UserObserverPlus, object: profile, action: read, allow: false},
|
||||
{user: test.UserTechnician, object: profile, action: read, allow: false},
|
||||
{user: test.UserGitOps, object: profile, action: read, allow: false},
|
||||
|
||||
{user: test.UserTeamAdminTeam1, object: profile, action: read, allow: true},
|
||||
{user: test.UserTeamMaintainerTeam1, object: profile, action: read, allow: true},
|
||||
{user: test.UserTeamObserverTeam1, object: profile, action: read, allow: false},
|
||||
{user: test.UserTeamObserverPlusTeam1, object: profile, action: read, allow: false},
|
||||
{user: test.UserTeamTechnicianTeam1, object: profile, action: read, allow: false},
|
||||
{user: test.UserTeamGitOpsTeam1, object: profile, action: read, allow: false},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAuthorizeMDMAppleBootstrapPackage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -356,23 +356,31 @@ func TestAppleMDMAuthorization(t *testing.T) {
|
||||
_, err = svc.NewMDMAppleDEPKeyPair(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Should work for all user types
|
||||
// The manual enrollment profile embeds the SCEP challenge, so only global
|
||||
// and team admins and maintainers can read it (same roles as enroll secrets).
|
||||
for _, user := range []*fleet.User{
|
||||
test.UserAdmin,
|
||||
test.UserMaintainer,
|
||||
test.UserObserver,
|
||||
test.UserObserverPlus,
|
||||
test.UserTeamAdminTeam1,
|
||||
test.UserTeamGitOpsTeam1,
|
||||
test.UserGitOps,
|
||||
test.UserTeamMaintainerTeam1,
|
||||
test.UserTeamObserverTeam1,
|
||||
test.UserTeamObserverPlusTeam1,
|
||||
} {
|
||||
usrctx := test.UserContext(ctx, user)
|
||||
_, err = svc.GetMDMManualEnrollmentProfile(usrctx, false)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
for _, user := range []*fleet.User{
|
||||
test.UserNoRoles,
|
||||
test.UserObserver,
|
||||
test.UserObserverPlus,
|
||||
test.UserGitOps,
|
||||
test.UserTeamObserverTeam1,
|
||||
test.UserTeamObserverPlusTeam1,
|
||||
test.UserTeamGitOpsTeam1,
|
||||
} {
|
||||
usrctx := test.UserContext(ctx, user)
|
||||
_, err = svc.GetMDMManualEnrollmentProfile(usrctx, false)
|
||||
checkAuthErr(t, err, true)
|
||||
}
|
||||
|
||||
// Must be device-authenticated, should fail
|
||||
_, err = svc.GetDeviceMDMAppleEnrollmentProfile(ctx)
|
||||
|
||||
Reference in New Issue
Block a user