or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

channel-builders.mdchannel-credentials.mdcontext-authorization.mdindex.mdserver-builders.mdserver-credentials.md

context-authorization.mddocs/

0

# Context and Authorization

1

2

Runtime context access for service identity verification and authorization checks in ALTS-secured gRPC communications.

3

4

## Capabilities

5

6

### ALTS Context

7

8

Provides access to ALTS authentication context information including peer service accounts and security levels.

9

10

```java { .api }

11

/**

12

* Contains ALTS authentication context information

13

*/

14

@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7864")

15

public final class AltsContext {

16

17

/**

18

* Creates a test instance of AltsContext for testing purposes

19

* @param peerServiceAccount the peer service account

20

* @param localServiceAccount the local service account

21

* @return AltsContext test instance

22

*/

23

public static AltsContext createTestInstance(String peerServiceAccount, String localServiceAccount);

24

25

/**

26

* Returns the security level of this context

27

* @return the SecurityLevel

28

*/

29

public SecurityLevel getSecurityLevel();

30

31

/**

32

* Returns the peer service account from the ALTS handshake

33

* @return the peer service account string

34

*/

35

public String getPeerServiceAccount();

36

37

/**

38

* Returns the local service account from the ALTS handshake

39

* @return the local service account string

40

*/

41

public String getLocalServiceAccount();

42

43

/**

44

* Security levels supported by ALTS

45

*/

46

public enum SecurityLevel {

47

/** Unknown security level */

48

UNKNOWN,

49

/** No security applied */

50

SECURITY_NONE,

51

/** Integrity protection only */

52

INTEGRITY_ONLY,

53

/** Both integrity and privacy protection */

54

INTEGRITY_AND_PRIVACY

55

}

56

}

57

```

58

59

**Usage Examples:**

60

61

```java

62

import io.grpc.alts.AltsContext;

63

import io.grpc.alts.AltsContextUtil;

64

import io.grpc.ServerCall;

65

66

// In a server interceptor or service method

67

public void handleRequest(ServerCall<?, ?> call) {

68

if (AltsContextUtil.check(call)) {

69

AltsContext context = AltsContextUtil.createFrom(call);

70

71

String peerAccount = context.getPeerServiceAccount();

72

String localAccount = context.getLocalServiceAccount();

73

AltsContext.SecurityLevel level = context.getSecurityLevel();

74

75

System.out.println("Peer: " + peerAccount);

76

System.out.println("Local: " + localAccount);

77

System.out.println("Security: " + level);

78

79

// Verify expected peer

80

if ("expected-client@project.iam.gserviceaccount.com".equals(peerAccount)) {

81

// Process request

82

} else {

83

// Reject request

84

}

85

}

86

}

87

88

// Testing context

89

AltsContext testContext = AltsContext.createTestInstance(

90

"test-peer@project.iam.gserviceaccount.com",

91

"test-local@project.iam.gserviceaccount.com"

92

);

93

```

94

95

### ALTS Context Utilities

96

97

Utility methods for extracting and checking ALTS context from gRPC calls.

98

99

```java { .api }

100

/**

101

* Utility methods for working with ALTS context

102

*/

103

@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7864")

104

public final class AltsContextUtil {

105

106

/**

107

* Creates AltsContext from a server call

108

* @param call the server call

109

* @return AltsContext or null if not available

110

*/

111

public static AltsContext createFrom(ServerCall<?, ?> call);

112

113

/**

114

* Creates AltsContext from a client call

115

* @param call the client call

116

* @return AltsContext or null if not available

117

*/

118

public static AltsContext createFrom(ClientCall<?, ?> call);

119

120

/**

121

* Creates AltsContext from transport attributes

122

* @param attributes the transport attributes

123

* @return AltsContext or null if not available

124

*/

125

public static AltsContext createFrom(Attributes attributes);

126

127

/**

128

* Checks if a server call contains ALTS information

129

* @param call the server call

130

* @return true if ALTS context is available

131

*/

132

public static boolean check(ServerCall<?, ?> call);

133

134

/**

135

* Checks if a client call contains ALTS information

136

* @param call the client call

137

* @return true if ALTS context is available

138

*/

139

public static boolean check(ClientCall<?, ?> call);

140

141

/**

142

* Checks if transport attributes contain ALTS information

143

* @param attributes the transport attributes

144

* @return true if ALTS context is available

145

*/

146

public static boolean check(Attributes attributes);

147

}

148

```

149

150

**Usage Examples:**

151

152

```java

153

import io.grpc.alts.AltsContextUtil;

154

import io.grpc.alts.AltsContext;

155

import io.grpc.ServerCall;

156

import io.grpc.ClientCall;

157

import io.grpc.Attributes;

158

159

// Server-side context extraction

160

public class AltsServerInterceptor implements ServerInterceptor {

161

@Override

162

public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(

163

ServerCall<ReqT, RespT> call,

164

Metadata headers,

165

ServerCallHandler<ReqT, RespT> next) {

166

167

if (AltsContextUtil.check(call)) {

168

AltsContext context = AltsContextUtil.createFrom(call);

169

if (context != null) {

170

// Log or validate the peer service account

171

System.out.println("ALTS peer: " + context.getPeerServiceAccount());

172

}

173

} else {

174

System.out.println("No ALTS context available");

175

}

176

177

return next.startCall(call, headers);

178

}

179

}

180

181

// Client-side context extraction

182

public class AltsClientInterceptor implements ClientInterceptor {

183

@Override

184

public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

185

MethodDescriptor<ReqT, RespT> method,

186

CallOptions callOptions,

187

Channel next) {

188

189

ClientCall<ReqT, RespT> call = next.newCall(method, callOptions);

190

191

// Check context after call completion

192

if (AltsContextUtil.check(call)) {

193

AltsContext context = AltsContextUtil.createFrom(call);

194

if (context != null) {

195

System.out.println("Server identity: " + context.getPeerServiceAccount());

196

}

197

}

198

199

return call;

200

}

201

}

202

203

// Transport attributes context extraction

204

public void handleTransportReady(Attributes attributes) {

205

if (AltsContextUtil.check(attributes)) {

206

AltsContext context = AltsContextUtil.createFrom(attributes);

207

if (context != null) {

208

System.out.println("Transport secured with ALTS");

209

System.out.println("Security level: " + context.getSecurityLevel());

210

}

211

}

212

}

213

```

214

215

### Authorization Utilities

216

217

Utility methods for performing authorization checks based on ALTS context.

218

219

```java { .api }

220

/**

221

* Utility methods for ALTS-based authorization

222

*/

223

public final class AuthorizationUtil {

224

225

/**

226

* Performs client authorization check against expected service accounts

227

* @param call the server call to check

228

* @param expectedServiceAccounts collection of expected service accounts

229

* @return Status.OK if authorized, error status otherwise

230

*/

231

public static Status clientAuthorizationCheck(

232

ServerCall<?, ?> call,

233

Collection<String> expectedServiceAccounts

234

);

235

}

236

```

237

238

**Usage Examples:**

239

240

```java

241

import io.grpc.alts.AuthorizationUtil;

242

import io.grpc.ServerCall;

243

import io.grpc.Status;

244

import java.util.Arrays;

245

import java.util.Collection;

246

247

// Server-side authorization

248

public class AuthorizingServiceImpl extends MyServiceGrpc.MyServiceImplBase {

249

250

private static final Collection<String> ALLOWED_CLIENTS = Arrays.asList(

251

"frontend@my-project.iam.gserviceaccount.com",

252

"batch-processor@my-project.iam.gserviceaccount.com"

253

);

254

255

@Override

256

public void myMethod(MyRequest request, StreamObserver<MyResponse> responseObserver) {

257

// Get the current server call

258

ServerCall<?, ?> call = getCurrentCall(); // Implementation-specific

259

260

// Perform authorization check

261

Status authStatus = AuthorizationUtil.clientAuthorizationCheck(call, ALLOWED_CLIENTS);

262

263

if (!authStatus.isOk()) {

264

responseObserver.onError(authStatus.asRuntimeException());

265

return;

266

}

267

268

// Process authorized request

269

MyResponse response = processRequest(request);

270

responseObserver.onNext(response);

271

responseObserver.onCompleted();

272

}

273

}

274

275

// Authorization in a server interceptor

276

public class AuthorizationInterceptor implements ServerInterceptor {

277

278

private final Collection<String> allowedServiceAccounts;

279

280

public AuthorizationInterceptor(Collection<String> allowedServiceAccounts) {

281

this.allowedServiceAccounts = allowedServiceAccounts;

282

}

283

284

@Override

285

public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(

286

ServerCall<ReqT, RespT> call,

287

Metadata headers,

288

ServerCallHandler<ReqT, RespT> next) {

289

290

Status authStatus = AuthorizationUtil.clientAuthorizationCheck(call, allowedServiceAccounts);

291

292

if (!authStatus.isOk()) {

293

call.close(authStatus, new Metadata());

294

return new ServerCall.Listener<ReqT>() {};

295

}

296

297

return next.startCall(call, headers);

298

}

299

}

300

```

301

302

## Security Context Pattern

303

304

Common pattern for accessing security context in service implementations:

305

306

```java

307

import io.grpc.alts.AltsContextUtil;

308

import io.grpc.alts.AltsContext;

309

import io.grpc.stub.StreamObserver;

310

311

public class SecureServiceImpl extends MyServiceGrpc.MyServiceImplBase {

312

313

@Override

314

public void secureMethod(MyRequest request, StreamObserver<MyResponse> responseObserver) {

315

// Access current call context

316

ServerCall<?, ?> call = getCurrentServerCall();

317

318

if (AltsContextUtil.check(call)) {

319

AltsContext altsContext = AltsContextUtil.createFrom(call);

320

321

// Use context for logging, authorization, or business logic

322

String clientServiceAccount = altsContext.getPeerServiceAccount();

323

AltsContext.SecurityLevel securityLevel = altsContext.getSecurityLevel();

324

325

// Log security information

326

System.out.printf("Request from %s with security level %s%n",

327

clientServiceAccount, securityLevel);

328

329

// Implement business logic with identity awareness

330

MyResponse response = handleSecureRequest(request, clientServiceAccount);

331

responseObserver.onNext(response);

332

responseObserver.onCompleted();

333

} else {

334

responseObserver.onError(

335

Status.UNAUTHENTICATED

336

.withDescription("ALTS authentication required")

337

.asRuntimeException()

338

);

339

}

340

}

341

342

private ServerCall<?, ?> getCurrentServerCall() {

343

// Implementation depends on how you access the current call

344

// This might involve ThreadLocal, Context propagation, or dependency injection

345

return null; // Placeholder

346

}

347

}

348

```

349

350

## Security Considerations

351

352

- **Context Availability**: ALTS context is only available for ALTS-secured connections

353

- **Service Account Validation**: Always validate peer service accounts against expected values

354

- **Security Level Checks**: Verify appropriate security levels for sensitive operations

355

- **Authorization Patterns**: Use `AuthorizationUtil` for consistent authorization checks

356

- **Testing**: Use `AltsContext.createTestInstance()` only in test environments