Skip to content

Commit 95e2f28

Browse files
[Core] Add NO_UPLOAD for remote_identity (#4307)
* Add skip flag to remote_identity * Rename to NO_UPLOAD * Fixes * lint * comments * Add comments * lint
1 parent e8d18e3 commit 95e2f28

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

docs/source/reference/config.rst

+18-3
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ Available fields and semantics:
244244
# instances. SkyPilot will auto-create and reuse a service account (IAM
245245
# role) for AWS instances.
246246
#
247+
# NO_UPLOAD: No credentials will be uploaded to the pods. Useful for
248+
# avoiding overriding any existing credentials that may be automounted on
249+
# the cluster.
250+
#
247251
# Customized service account (IAM role): <string> or <list of single-element dict>
248252
# - <string>: apply the service account with the specified name to all instances.
249253
# Example:
@@ -263,7 +267,8 @@ Available fields and semantics:
263267
#
264268
# - This only affects AWS instances. Local AWS credentials will still be
265269
# uploaded to non-AWS instances (since those instances may need to access
266-
# AWS resources).
270+
# AWS resources). To fully disable credential upload, set
271+
# `remote_identity: NO_UPLOAD`.
267272
# - If the SkyPilot jobs/serve controller is on AWS, this setting will make
268273
# non-AWS managed jobs / non-AWS service replicas fail to access any
269274
# resources on AWS (since the controllers don't have AWS credential
@@ -406,11 +411,16 @@ Available fields and semantics:
406411
# instances. SkyPilot will auto-create and reuse a service account for GCP
407412
# instances.
408413
#
414+
# NO_UPLOAD: No credentials will be uploaded to the pods. Useful for
415+
# avoiding overriding any existing credentials that may be automounted on
416+
# the cluster.
417+
#
409418
# Two caveats of SERVICE_ACCOUNT for multicloud users:
410419
#
411420
# - This only affects GCP instances. Local GCP credentials will still be
412421
# uploaded to non-GCP instances (since those instances may need to access
413-
# GCP resources).
422+
# GCP resources). To fully disable credential uploads, set
423+
# `remote_identity: NO_UPLOAD`.
414424
# - If the SkyPilot jobs/serve controller is on GCP, this setting will make
415425
# non-GCP managed jobs / non-GCP service replicas fail to access any
416426
# resources on GCP (since the controllers don't have GCP credential
@@ -497,6 +507,10 @@ Available fields and semantics:
497507
# SkyPilot will auto-create and reuse a service account with necessary roles
498508
# in the user's namespace.
499509
#
510+
# NO_UPLOAD: No credentials will be uploaded to the pods. Useful for
511+
# avoiding overriding any existing credentials that may be automounted on
512+
# the cluster.
513+
#
500514
# <string>: The name of a service account to use for all Kubernetes pods.
501515
# This service account must exist in the user's namespace and have all
502516
# necessary permissions. Refer to https://skypilot.readthedocs.io/en/latest/cloud-setup/cloud-permissions/kubernetes.html
@@ -505,7 +519,8 @@ Available fields and semantics:
505519
# Using SERVICE_ACCOUNT or a custom service account only affects Kubernetes
506520
# instances. Local ~/.kube/config will still be uploaded to non-Kubernetes
507521
# instances (e.g., a serve controller on GCP or AWS may need to provision
508-
# Kubernetes resources).
522+
# Kubernetes resources). To fully disable credential uploads, set
523+
# `remote_identity: NO_UPLOAD`.
509524
#
510525
# Default: 'SERVICE_ACCOUNT'.
511526
remote_identity: my-k8s-service-account

sky/backends/backend_utils.py

+33-3
Original file line numberDiff line numberDiff line change
@@ -690,26 +690,56 @@ def write_cluster_config(
690690
skypilot_config.get_nested(
691691
(str(to_provision.cloud).lower(), 'specific_reservations'), set()))
692692

693+
# Remote identity handling can have 4 cases:
694+
# 1. LOCAL_CREDENTIALS (default for most clouds): Upload local credentials
695+
# 2. SERVICE_ACCOUNT: SkyPilot creates and manages a service account
696+
# 3. Custom service account: Use specified service account
697+
# 4. NO_UPLOAD: Do not upload any credentials
698+
#
699+
# We need to upload credentials only if LOCAL_CREDENTIALS is specified. In
700+
# other cases, we exclude the cloud from credential file uploads after
701+
# running required checks.
693702
assert cluster_name is not None
694-
excluded_clouds = []
703+
excluded_clouds = set()
695704
remote_identity_config = skypilot_config.get_nested(
696705
(str(cloud).lower(), 'remote_identity'), None)
697706
remote_identity = schemas.get_default_remote_identity(str(cloud).lower())
698707
if isinstance(remote_identity_config, str):
699708
remote_identity = remote_identity_config
700709
if isinstance(remote_identity_config, list):
710+
# Some clouds (e.g., AWS) support specifying multiple service accounts
711+
# chosen based on the cluster name. Do the matching here to pick the
712+
# correct one.
701713
for profile in remote_identity_config:
702714
if fnmatch.fnmatchcase(cluster_name, list(profile.keys())[0]):
703715
remote_identity = list(profile.values())[0]
704716
break
705717
if remote_identity != schemas.RemoteIdentityOptions.LOCAL_CREDENTIALS.value:
706-
if not cloud.supports_service_account_on_remote():
718+
# If LOCAL_CREDENTIALS is not specified, we add the cloud to the
719+
# excluded_clouds set, but we must also check if the cloud supports
720+
# service accounts.
721+
if remote_identity == schemas.RemoteIdentityOptions.NO_UPLOAD.value:
722+
# If NO_UPLOAD is specified, fall back to default remote identity
723+
# for downstream logic but add it to excluded_clouds to skip
724+
# credential file uploads.
725+
remote_identity = schemas.get_default_remote_identity(
726+
str(cloud).lower())
727+
elif not cloud.supports_service_account_on_remote():
707728
raise exceptions.InvalidCloudConfigs(
708729
'remote_identity: SERVICE_ACCOUNT is specified in '
709730
f'{skypilot_config.loaded_config_path!r} for {cloud}, but it '
710731
'is not supported by this cloud. Remove the config or set: '
711732
'`remote_identity: LOCAL_CREDENTIALS`.')
712-
excluded_clouds = [cloud]
733+
excluded_clouds.add(cloud)
734+
735+
for cloud_str, cloud_obj in cloud_registry.CLOUD_REGISTRY.items():
736+
remote_identity_config = skypilot_config.get_nested(
737+
(cloud_str.lower(), 'remote_identity'), None)
738+
if remote_identity_config:
739+
if (remote_identity_config ==
740+
schemas.RemoteIdentityOptions.NO_UPLOAD.value):
741+
excluded_clouds.add(cloud_obj)
742+
713743
credentials = sky_check.get_cloud_credential_file_mounts(excluded_clouds)
714744

715745
auth_config = {'ssh_private_key': auth.PRIVATE_SSH_KEY_PATH}

sky/utils/schemas.py

+1
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ class RemoteIdentityOptions(enum.Enum):
663663
"""
664664
LOCAL_CREDENTIALS = 'LOCAL_CREDENTIALS'
665665
SERVICE_ACCOUNT = 'SERVICE_ACCOUNT'
666+
NO_UPLOAD = 'NO_UPLOAD'
666667

667668

668669
def get_default_remote_identity(cloud: str) -> str:

0 commit comments

Comments
 (0)