0
# Security Framework
1
2
Security abstractions including authentication annotations, authorization enforcement, SSL/TLS configuration, and audit logging capabilities.
3
4
## Capabilities
5
6
### Authentication and Authorization Annotations
7
8
Annotations for declarative security enforcement in CDAP components.
9
10
```java { .api }
11
/**
12
* Annotation for authorization enforcement
13
*/
14
@Target({ElementType.METHOD, ElementType.TYPE})
15
@Retention(RetentionPolicy.RUNTIME)
16
public @interface AuthEnforce {
17
/**
18
* List of entities to check authorization for
19
* @return Array of entity patterns
20
*/
21
String[] value() default {};
22
}
23
24
/**
25
* Annotation for audit policy configuration
26
*/
27
@Target({ElementType.METHOD, ElementType.TYPE})
28
@Retention(RetentionPolicy.RUNTIME)
29
public @interface AuditPolicy {
30
/**
31
* Audit policy value
32
*/
33
String value();
34
}
35
36
/**
37
* Annotation for specifying audit details
38
*/
39
@Target(ElementType.PARAMETER)
40
@Retention(RetentionPolicy.RUNTIME)
41
public @interface AuditDetail {
42
/**
43
* Name of the audit detail field
44
*/
45
String value();
46
}
47
```
48
49
**Usage Examples:**
50
51
```java
52
import io.cdap.cdap.common.security.*;
53
54
// Method-level authorization
55
@Path("/api/v1/namespaces/{namespace}")
56
public class NamespaceHandler {
57
58
@GET
59
@Path("/applications")
60
@AuthEnforce("namespace:{namespace}")
61
@AuditPolicy("APPLICATION_LIST")
62
public void listApplications(@PathParam("namespace") @AuditDetail("namespace") String namespace,
63
HttpRequest request, HttpResponder responder) {
64
// This method requires authorization for the specified namespace
65
// and will be audited with the APPLICATION_LIST policy
66
List<Application> apps = applicationService.listApplications(namespace);
67
responder.sendJson(HttpResponseStatus.OK, apps);
68
}
69
70
@DELETE
71
@Path("/applications/{app}")
72
@AuthEnforce({"namespace:{namespace}", "application:{app}"})
73
@AuditPolicy("APPLICATION_DELETE")
74
public void deleteApplication(@PathParam("namespace") @AuditDetail("namespace") String namespace,
75
@PathParam("app") @AuditDetail("application") String appName,
76
HttpRequest request, HttpResponder responder) {
77
// Requires authorization for both namespace and application
78
applicationService.deleteApplication(namespace, appName);
79
responder.sendStatus(HttpResponseStatus.OK);
80
}
81
}
82
83
// Class-level authorization
84
@AuthEnforce("admin")
85
@AuditPolicy("ADMIN_OPERATION")
86
@Path("/admin")
87
public class AdminHandler {
88
89
@POST
90
@Path("/reset")
91
public void resetSystem(HttpRequest request, HttpResponder responder) {
92
// All methods in this class require admin authorization
93
systemService.reset();
94
responder.sendStatus(HttpResponseStatus.OK);
95
}
96
}
97
```
98
99
### SSL/TLS and KeyStore Management
100
101
Utilities for SSL/TLS configuration and keystore management.
102
103
```java { .api }
104
/**
105
* KeyStore management utilities
106
*/
107
public class KeyStores {
108
/**
109
* Generate a self-signed certificate keystore
110
*/
111
public static KeyStore generatedCertKeyStore(SConfiguration sConf, String password)
112
throws GeneralSecurityException, IOException;
113
114
/**
115
* Load keystore from file
116
*/
117
public static KeyStore load(File keystoreFile, String password, String type)
118
throws GeneralSecurityException, IOException;
119
120
/**
121
* Create empty keystore of specified type
122
*/
123
public static KeyStore createEmpty(String type) throws GeneralSecurityException;
124
125
/**
126
* Get certificate from keystore
127
*/
128
public static Certificate getCertificate(KeyStore keyStore, String alias)
129
throws KeyStoreException;
130
}
131
132
/**
133
* HTTPS configuration enabler
134
*/
135
public class HttpsEnabler {
136
/**
137
* Enable HTTPS for the given configuration
138
*/
139
public static void enable(CConfiguration cConf, SConfiguration sConf);
140
141
/**
142
* Check if HTTPS is enabled in configuration
143
*/
144
public static boolean isEnabled(CConfiguration cConf);
145
146
/**
147
* Get SSL context from configuration
148
*/
149
public static SSLContext getSSLContext(CConfiguration cConf, SConfiguration sConf)
150
throws GeneralSecurityException, IOException;
151
}
152
```
153
154
### YARN Token Utilities
155
156
Utilities for managing YARN delegation tokens in secure environments.
157
158
```java { .api }
159
/**
160
* YARN delegation token utilities
161
*/
162
public class YarnTokenUtils {
163
/**
164
* Obtain delegation tokens for YARN services
165
*/
166
public static Credentials obtainTokens(Configuration yarnConf, Credentials credentials)
167
throws IOException, InterruptedException;
168
169
/**
170
* Add delegation tokens to user credentials
171
*/
172
public static void addTokens(Configuration yarnConf, Credentials credentials,
173
String user, File tokenFile) throws IOException;
174
175
/**
176
* Write tokens to file
177
*/
178
public static void writeTokens(Credentials credentials, File tokenFile) throws IOException;
179
180
/**
181
* Read tokens from file
182
*/
183
public static Credentials readTokens(File tokenFile) throws IOException;
184
185
/**
186
* Check if tokens are valid and not expired
187
*/
188
public static boolean areTokensValid(Credentials credentials);
189
}
190
```
191
192
### Authorization Enforcement Utilities
193
194
Utilities for programmatic authorization enforcement.
195
196
```java { .api }
197
/**
198
* Authorization enforcement utilities
199
*/
200
public class AuthEnforceUtil {
201
/**
202
* Extract authorization entities from method annotations
203
*/
204
public static Set<String> getAuthorizeEntities(Method method, Object[] args);
205
206
/**
207
* Check if method requires authorization
208
*/
209
public static boolean requiresAuthorization(Method method);
210
211
/**
212
* Get audit policy from method or class annotations
213
*/
214
public static String getAuditPolicy(Method method, Class<?> clazz);
215
216
/**
217
* Extract audit details from method parameters
218
*/
219
public static Map<String, String> getAuditDetails(Method method, Object[] args);
220
221
/**
222
* Resolve entity patterns with actual parameter values
223
*/
224
public static Set<String> resolveEntityPatterns(String[] patterns,
225
Method method, Object[] args);
226
}
227
```
228
229
**Advanced Usage Examples:**
230
231
```java
232
import io.cdap.cdap.common.security.*;
233
import javax.net.ssl.SSLContext;
234
import java.security.KeyStore;
235
236
// SSL/TLS configuration
237
public class SecureServiceConfig {
238
private final CConfiguration cConf;
239
private final SConfiguration sConf;
240
241
public SecureServiceConfig(CConfiguration cConf, SConfiguration sConf) {
242
this.cConf = cConf;
243
this.sConf = sConf;
244
}
245
246
public void configureSSL() throws Exception {
247
if (HttpsEnabler.isEnabled(cConf)) {
248
// Generate or load keystore
249
String keystorePassword = sConf.get("ssl.keystore.password", "changeit");
250
KeyStore keyStore = KeyStores.generatedCertKeyStore(sConf, keystorePassword);
251
252
// Get SSL context
253
SSLContext sslContext = HttpsEnabler.getSSLContext(cConf, sConf);
254
255
// Configure SSL for services
256
configureServiceSSL(sslContext, keyStore);
257
}
258
}
259
260
private void configureServiceSSL(SSLContext sslContext, KeyStore keyStore) {
261
// Configure SSL settings for Netty services, etc.
262
}
263
}
264
265
// YARN security integration
266
public class SecureYarnClient {
267
public void setupSecureClient(Configuration yarnConf, String user) throws Exception {
268
Credentials credentials = new Credentials();
269
270
// Obtain delegation tokens
271
YarnTokenUtils.obtainTokens(yarnConf, credentials);
272
273
// Write tokens to file for secure access
274
File tokenFile = new File("/tmp/yarn-tokens");
275
YarnTokenUtils.writeTokens(credentials, tokenFile);
276
277
// Add tokens to user credentials
278
YarnTokenUtils.addTokens(yarnConf, credentials, user, tokenFile);
279
280
// Check token validity
281
if (!YarnTokenUtils.areTokensValid(credentials)) {
282
System.out.println("Warning: Some tokens may be expired");
283
}
284
}
285
286
public void refreshTokens(Configuration yarnConf, File tokenFile) throws Exception {
287
// Read existing tokens
288
Credentials existing = YarnTokenUtils.readTokens(tokenFile);
289
290
if (!YarnTokenUtils.areTokensValid(existing)) {
291
// Obtain fresh tokens
292
Credentials fresh = YarnTokenUtils.obtainTokens(yarnConf, new Credentials());
293
YarnTokenUtils.writeTokens(fresh, tokenFile);
294
}
295
}
296
}
297
298
// Authorization enforcement
299
public class SecurityEnforcer {
300
public void enforceAuthorization(Method method, Object[] args,
301
AuthorizationContext authContext) throws ForbiddenException {
302
303
if (!AuthEnforceUtil.requiresAuthorization(method)) {
304
return; // No authorization required
305
}
306
307
// Get entities to authorize
308
Set<String> entities = AuthEnforceUtil.getAuthorizeEntities(method, args);
309
310
// Check authorization for each entity
311
for (String entity : entities) {
312
if (!authContext.isAuthorized(entity)) {
313
throw new ForbiddenException("Not authorized for entity: " + entity);
314
}
315
}
316
}
317
318
public void auditMethodCall(Method method, Object[] args, String user) {
319
String auditPolicy = AuthEnforceUtil.getAuditPolicy(method, method.getDeclaringClass());
320
321
if (auditPolicy != null) {
322
Map<String, String> auditDetails = AuthEnforceUtil.getAuditDetails(method, args);
323
auditDetails.put("user", user);
324
auditDetails.put("method", method.getName());
325
326
// Log audit event
327
auditLogger.log(auditPolicy, auditDetails);
328
}
329
}
330
}
331
332
// Custom authorization aspect/interceptor
333
public class AuthorizationInterceptor implements MethodInterceptor {
334
private final SecurityEnforcer securityEnforcer;
335
private final AuthorizationContext authContext;
336
337
public AuthorizationInterceptor(SecurityEnforcer securityEnforcer,
338
AuthorizationContext authContext) {
339
this.securityEnforcer = securityEnforcer;
340
this.authContext = authContext;
341
}
342
343
@Override
344
public Object invoke(MethodInvocation invocation) throws Throwable {
345
Method method = invocation.getMethod();
346
Object[] args = invocation.getArguments();
347
348
// Enforce authorization
349
securityEnforcer.enforceAuthorization(method, args, authContext);
350
351
// Audit the method call
352
String user = authContext.getPrincipal().getName();
353
securityEnforcer.auditMethodCall(method, args, user);
354
355
// Proceed with method execution
356
return invocation.proceed();
357
}
358
}
359
```