mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-15 11:28:09 +00:00
SP Guest Account Access locked down by default and deploying user added as admin. (#1425)
* Service Principal locked down by default and deploying user added. * Fixing call to client. * Adding multiple users. * Retrieving SP id. * Refactorin gcall. * Getting closer. * Can retrieve object_id from create * New retrieve sp functionality. * mypy fixes. * Separating functionality into new function. * mypy errors. * Logic for updating appRoleAssignemntRequired param. * Changing to patch. * Updating to Patch. * Fixing bug. * Fixing bad assignment. * Responding to comments. * Removing functionality for updating setting. * Update src/deployment/deploy.py Co-authored-by: Cheick Keita <kcheick@gmail.com> * UPdating error message. * Retriggering? * Trying to emulate new file structure. * Fixing lint issues. * Fixing create sp. Co-authored-by: nharper285 <nharper285@gmail.com> Co-authored-by: Cheick Keita <kcheick@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6b64b60da7
commit
de2b7cabd0
@ -60,9 +60,12 @@ from deploylib.registration import (
|
||||
GraphQueryError,
|
||||
OnefuzzAppRole,
|
||||
add_application_password,
|
||||
add_user,
|
||||
assign_instance_app_role,
|
||||
authorize_application,
|
||||
get_application,
|
||||
get_service_principal,
|
||||
get_signed_in_user,
|
||||
get_tenant_id,
|
||||
query_microsoft_graph,
|
||||
register_application,
|
||||
@ -300,7 +303,6 @@ class Client:
|
||||
display_name=self.application_name,
|
||||
subscription_id=self.get_subscription_id(),
|
||||
)
|
||||
|
||||
app_roles = [
|
||||
{
|
||||
"allowedMemberTypes": ["Application"],
|
||||
@ -318,6 +320,14 @@ class Client:
|
||||
"isEnabled": True,
|
||||
"value": OnefuzzAppRole.ManagedNode.value,
|
||||
},
|
||||
{
|
||||
"allowedMemberTypes": ["User"],
|
||||
"description": "Allows user access from the CLI.",
|
||||
"displayName": OnefuzzAppRole.UserAssignment.value,
|
||||
"id": str(uuid.uuid4()),
|
||||
"isEnabled": True,
|
||||
"value": OnefuzzAppRole.UserAssignment.value,
|
||||
},
|
||||
]
|
||||
|
||||
if not app:
|
||||
@ -372,7 +382,7 @@ class Client:
|
||||
|
||||
service_principal_params = {
|
||||
"accountEnabled": True,
|
||||
"appRoleAssignmentRequired": False,
|
||||
"appRoleAssignmentRequired": True,
|
||||
"servicePrincipalType": "Application",
|
||||
"appId": app["appId"],
|
||||
}
|
||||
@ -431,11 +441,10 @@ class Client:
|
||||
# this is a requirement to update the application roles
|
||||
for role in app["appRoles"]:
|
||||
role["isEnabled"] = False
|
||||
|
||||
query_microsoft_graph(
|
||||
method="PATCH",
|
||||
resource=f"applications/{app['id']}",
|
||||
body={"appRoles": app["AppRoles"]},
|
||||
body={"appRoles": app["appRoles"]},
|
||||
subscription=self.get_subscription_id(),
|
||||
)
|
||||
|
||||
@ -603,6 +612,37 @@ class Client:
|
||||
OnefuzzAppRole.ManagedNode,
|
||||
)
|
||||
|
||||
def assign_user_access(self) -> None:
|
||||
logger.info("assinging user access to service principal")
|
||||
app = get_application(
|
||||
display_name=self.application_name,
|
||||
subscription_id=self.get_subscription_id(),
|
||||
)
|
||||
user = get_signed_in_user(self.subscription_id)
|
||||
|
||||
if app:
|
||||
sp = get_service_principal(app["appId"], self.subscription_id)
|
||||
# Update appRoleAssignmentRequired if necessary
|
||||
if not sp["appRoleAssignmentRequired"]:
|
||||
logger.warning(
|
||||
"The service is not currently configured to require a role assignment to access it."
|
||||
+ " This means that any authenticated user can access the service. "
|
||||
+ " To change this behavior enable 'Assignment Required?' on the service principal in the AAD Portal."
|
||||
)
|
||||
|
||||
# Assign Roles and Add Users
|
||||
roles = [
|
||||
x["id"]
|
||||
for x in app["appRoles"]
|
||||
if x["displayName"] == OnefuzzAppRole.UserAssignment.value
|
||||
]
|
||||
users = [user["id"]]
|
||||
if self.admins:
|
||||
admins_str = [str(x) for x in self.admins]
|
||||
users += admins_str
|
||||
for user_id in users:
|
||||
add_user(sp["id"], user_id, roles[0])
|
||||
|
||||
def apply_migrations(self) -> None:
|
||||
logger.info("applying database migrations")
|
||||
name = self.results["deploy"]["func-name"]["value"]
|
||||
@ -983,6 +1023,7 @@ def main() -> None:
|
||||
("rbac", Client.setup_rbac),
|
||||
("arm", Client.deploy_template),
|
||||
("assign_scaleset_identity_role", Client.assign_scaleset_identity_role),
|
||||
("assign_user_access", Client.assign_user_access),
|
||||
]
|
||||
|
||||
full_deployment_states = rbac_only_states + [
|
||||
|
@ -154,6 +154,7 @@ class ApplicationInfo(NamedTuple):
|
||||
class OnefuzzAppRole(Enum):
|
||||
ManagedNode = "ManagedNode"
|
||||
CliClient = "CliClient"
|
||||
UserAssignment = "UserAssignment"
|
||||
|
||||
|
||||
def register_application(
|
||||
@ -646,6 +647,84 @@ def set_app_audience(
|
||||
raise Exception(err_str)
|
||||
|
||||
|
||||
def get_signed_in_user(subscription_id: Optional[str]) -> Any:
|
||||
# Get principalId by retrieving owner for SP
|
||||
try:
|
||||
app = query_microsoft_graph(
|
||||
method="GET",
|
||||
resource="me/",
|
||||
subscription=subscription_id,
|
||||
)
|
||||
return app
|
||||
|
||||
except GraphQueryError:
|
||||
query = (
|
||||
"az rest --method post --url "
|
||||
"https://graph.microsoft.com/v1.0/me "
|
||||
'--headers "Content-Type"=application/json'
|
||||
)
|
||||
logger.warning(
|
||||
"execute the following query in the azure portal bash shell and "
|
||||
"run deploy.py again : \n%s",
|
||||
query,
|
||||
)
|
||||
err_str = "Unable to retrieve signed-in user via Microsoft Graph Query API. \n"
|
||||
raise Exception(err_str)
|
||||
|
||||
|
||||
def get_service_principal(app_id: str, subscription_id: Optional[str]) -> Any:
|
||||
try:
|
||||
service_principals = query_microsoft_graph_list(
|
||||
method="GET",
|
||||
resource="servicePrincipals",
|
||||
params={"$filter": f"appId eq '{app_id}'"},
|
||||
subscription=subscription_id,
|
||||
)
|
||||
if len(service_principals) != 0:
|
||||
return service_principals[0]
|
||||
else:
|
||||
raise GraphQueryError(
|
||||
f"Could not retrieve any service principals for App Id: {app_id}", 400
|
||||
)
|
||||
|
||||
except GraphQueryError:
|
||||
err_str = "Unable to add retrieve SP using Microsoft Graph Query API. \n"
|
||||
raise Exception(err_str)
|
||||
|
||||
|
||||
def add_user(object_id: str, principal_id: str, role_id: str) -> None:
|
||||
# Get principalId by retrieving owner for SP
|
||||
# need to add users with proper role assignment
|
||||
http_body = {
|
||||
"principalId": principal_id,
|
||||
"resourceId": object_id,
|
||||
"appRoleId": role_id,
|
||||
}
|
||||
try:
|
||||
query_microsoft_graph(
|
||||
method="POST",
|
||||
resource="users/%s/appRoleAssignments" % principal_id,
|
||||
body=http_body,
|
||||
)
|
||||
except GraphQueryError as ex:
|
||||
if "Permission being assigned already exists" not in ex.message:
|
||||
query = (
|
||||
"az rest --method post --url "
|
||||
"https://graph.microsoft.com/v1.0/users/%s/appRoleAssignments "
|
||||
"--body '%s' --headers \"Content-Type\"=application/json"
|
||||
% (principal_id, http_body)
|
||||
)
|
||||
logger.warning(
|
||||
"execute the following query in the azure portal bash shell and "
|
||||
"run deploy.py again : \n%s",
|
||||
query,
|
||||
)
|
||||
err_str = "Unable to add user to SP using Microsoft Graph Query API. \n"
|
||||
raise Exception(err_str)
|
||||
else:
|
||||
logger.info("User already assigned to application.")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
formatter = argparse.ArgumentDefaultsHelpFormatter
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Licensed under the MIT License.
|
||||
|
||||
import unittest
|
||||
from typing import Any, List
|
||||
from typing import Any
|
||||
|
||||
from deploylib.configuration import NetworkSecurityConfig
|
||||
|
||||
|
Reference in New Issue
Block a user