or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

clients.mdenvironments.mdindex.mdssh-keys.md

ssh-keys.mddocs/

0

# SSH Key Management

1

2

Operations for managing SSH public keys associated with Cloud Shell environments, enabling secure SSH connections to running environments.

3

4

## Capabilities

5

6

### Add Public Key

7

8

Add an SSH public key to a Cloud Shell environment (long-running operation).

9

10

```python { .api }

11

def add_public_key(

12

self,

13

request: Optional[Union[cloudshell.AddPublicKeyRequest, dict]] = None,

14

*,

15

retry: OptionalRetry = gapic_v1.method.DEFAULT,

16

timeout: Union[float, object] = gapic_v1.method.DEFAULT,

17

metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),

18

) -> operation.Operation:

19

"""

20

Add public SSH key to environment. This is a long-running operation.

21

22

Args:

23

request: AddPublicKeyRequest object or dict

24

retry: Retry configuration for the request

25

timeout: Timeout for the request

26

metadata: Additional metadata to send with the request

27

28

Returns:

29

Long-running operation that resolves to AddPublicKeyResponse

30

31

Raises:

32

google.api_core.exceptions.GoogleAPICallError: API call failed

33

google.api_core.exceptions.InvalidArgument: Invalid SSH key format

34

"""

35

```

36

37

### Remove Public Key

38

39

Remove an SSH public key from a Cloud Shell environment (long-running operation).

40

41

```python { .api }

42

def remove_public_key(

43

self,

44

request: Optional[Union[cloudshell.RemovePublicKeyRequest, dict]] = None,

45

*,

46

retry: OptionalRetry = gapic_v1.method.DEFAULT,

47

timeout: Union[float, object] = gapic_v1.method.DEFAULT,

48

metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),

49

) -> operation.Operation:

50

"""

51

Remove public SSH key from environment. This is a long-running operation.

52

53

Args:

54

request: RemovePublicKeyRequest object or dict

55

retry: Retry configuration for the request

56

timeout: Timeout for the request

57

metadata: Additional metadata to send with the request

58

59

Returns:

60

Long-running operation that resolves to RemovePublicKeyResponse

61

62

Raises:

63

google.api_core.exceptions.GoogleAPICallError: API call failed

64

google.api_core.exceptions.NotFound: SSH key not found

65

"""

66

```

67

68

## Request Types

69

70

### AddPublicKeyRequest

71

72

```python { .api }

73

class AddPublicKeyRequest(proto.Message):

74

"""Request to add SSH public key to environment."""

75

76

environment: str # Environment name (e.g., users/me/environments/default)

77

key: str # SSH public key in supported format (OpenSSH format)

78

```

79

80

### RemovePublicKeyRequest

81

82

```python { .api }

83

class RemovePublicKeyRequest(proto.Message):

84

"""Request to remove SSH public key from environment."""

85

86

environment: str # Environment name (e.g., users/me/environments/default)

87

key: str # SSH public key to remove (must match exactly)

88

```

89

90

## Response Types

91

92

### AddPublicKeyResponse

93

94

```python { .api }

95

class AddPublicKeyResponse(proto.Message):

96

"""Response from add public key operation."""

97

98

key: str # Key that was added (normalized format)

99

```

100

101

### RemovePublicKeyResponse

102

103

```python { .api }

104

class RemovePublicKeyResponse(proto.Message):

105

"""Response from remove public key operation."""

106

# Empty message

107

```

108

109

## Operation Metadata Types

110

111

### AddPublicKeyMetadata

112

113

```python { .api }

114

class AddPublicKeyMetadata(proto.Message):

115

"""Operation metadata for add key operations."""

116

# Empty message

117

```

118

119

### RemovePublicKeyMetadata

120

121

```python { .api }

122

class RemovePublicKeyMetadata(proto.Message):

123

"""Operation metadata for remove key operations."""

124

# Empty message

125

```

126

127

## Usage Examples

128

129

### Add SSH Public Key

130

131

```python

132

from google.cloud.shell import CloudShellServiceClient, AddPublicKeyRequest

133

134

client = CloudShellServiceClient()

135

136

# Read SSH public key from file

137

with open("~/.ssh/id_rsa.pub", "r") as f:

138

public_key = f.read().strip()

139

140

request = AddPublicKeyRequest(

141

environment="users/me/environments/default",

142

key=public_key

143

)

144

145

operation = client.add_public_key(request=request)

146

print(f"Operation name: {operation.name}")

147

148

# Wait for completion

149

response = operation.result()

150

print(f"Added key: {response.key[:50]}...")

151

```

152

153

### Remove SSH Public Key

154

155

```python

156

from google.cloud.shell import CloudShellServiceClient, RemovePublicKeyRequest

157

158

client = CloudShellServiceClient()

159

160

# Get current environment to see existing keys

161

environment = client.get_environment(

162

name="users/me/environments/default"

163

)

164

165

if environment.public_keys:

166

# Remove the first key

167

key_to_remove = environment.public_keys[0]

168

169

request = RemovePublicKeyRequest(

170

environment="users/me/environments/default",

171

key=key_to_remove

172

)

173

174

operation = client.remove_public_key(request=request)

175

operation.result()

176

print("SSH key removed successfully")

177

else:

178

print("No SSH keys to remove")

179

```

180

181

### Manage Multiple SSH Keys

182

183

```python

184

from google.cloud.shell import CloudShellServiceClient

185

import os

186

import glob

187

188

client = CloudShellServiceClient()

189

190

# Add multiple SSH keys from ~/.ssh directory

191

ssh_dir = os.path.expanduser("~/.ssh")

192

pub_key_files = glob.glob(os.path.join(ssh_dir, "*.pub"))

193

194

for key_file in pub_key_files:

195

with open(key_file, "r") as f:

196

public_key = f.read().strip()

197

198

operation = client.add_public_key(

199

environment="users/me/environments/default",

200

key=public_key

201

)

202

203

try:

204

response = operation.result(timeout=60)

205

print(f"Added key from {key_file}")

206

except Exception as e:

207

print(f"Failed to add key from {key_file}: {e}")

208

```

209

210

### List Current SSH Keys

211

212

```python

213

from google.cloud.shell import CloudShellServiceClient

214

215

client = CloudShellServiceClient()

216

217

environment = client.get_environment(

218

name="users/me/environments/default"

219

)

220

221

print(f"Environment has {len(environment.public_keys)} SSH keys:")

222

for i, key in enumerate(environment.public_keys):

223

# Show first and last 20 characters of each key

224

key_preview = f"{key[:20]}...{key[-20:]}" if len(key) > 40 else key

225

print(f" {i+1}. {key_preview}")

226

```

227

228

### Async SSH Key Management

229

230

```python

231

import asyncio

232

from google.cloud.shell import CloudShellServiceAsyncClient, AddPublicKeyRequest

233

234

async def manage_ssh_keys():

235

async with CloudShellServiceAsyncClient() as client:

236

# Add key

237

with open("~/.ssh/id_ed25519.pub", "r") as f:

238

public_key = f.read().strip()

239

240

add_operation = await client.add_public_key(

241

AddPublicKeyRequest(

242

environment="users/me/environments/default",

243

key=public_key

244

)

245

)

246

247

response = await add_operation.result()

248

print(f"Added SSH key: {response.key[:50]}...")

249

250

# Verify key was added

251

environment = await client.get_environment(

252

name="users/me/environments/default"

253

)

254

print(f"Environment now has {len(environment.public_keys)} SSH keys")

255

256

asyncio.run(manage_ssh_keys())

257

```

258

259

### Error Handling

260

261

```python

262

from google.cloud.shell import CloudShellServiceClient, AddPublicKeyRequest

263

from google.api_core import exceptions

264

265

client = CloudShellServiceClient()

266

267

try:

268

# Try to add invalid SSH key

269

operation = client.add_public_key(

270

AddPublicKeyRequest(

271

environment="users/me/environments/default",

272

key="invalid-ssh-key-format"

273

)

274

)

275

response = operation.result()

276

except exceptions.InvalidArgument as e:

277

print(f"Invalid SSH key format: {e}")

278

except exceptions.GoogleAPICallError as e:

279

print(f"API call failed: {e}")

280

```

281

282

### SSH Key Formats

283

284

The Google Cloud Shell API supports SSH public keys in OpenSSH format. Common key types include:

285

286

#### RSA Key Example

287

```

288

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7YjmZH3+l8f... user@example.com

289

```

290

291

#### Ed25519 Key Example

292

```

293

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILhLxNd8s6+m... user@example.com

294

```

295

296

#### ECDSA Key Example

297

```

298

ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY... user@example.com

299

```

300

301

### Best Practices

302

303

1. **Key Generation**: Generate strong SSH keys using `ssh-keygen -t ed25519` or `ssh-keygen -t rsa -b 4096`

304

2. **Key Management**: Regularly rotate SSH keys and remove unused keys

305

3. **Error Handling**: Always handle potential errors like invalid key formats or network failures

306

4. **Environment State**: Check environment state before managing keys - some operations may require the environment to be running

307

5. **Key Persistence**: SSH keys persist across environment restarts but may be removed when environments are deleted