CDAP Common provides core common utilities and abstractions for the CDAP (Cask Data Application Platform) ecosystem including exception handling, service management, configuration, HTTP utilities, metadata management, security abstractions, discovery services, and various utility classes that are shared across CDAP components.
—
Security abstractions including authentication annotations, authorization enforcement, SSL/TLS configuration, and audit logging capabilities.
Annotations for declarative security enforcement in CDAP components.
/**
* Annotation for authorization enforcement
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthEnforce {
/**
* List of entities to check authorization for
* @return Array of entity patterns
*/
String[] value() default {};
}
/**
* Annotation for audit policy configuration
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditPolicy {
/**
* Audit policy value
*/
String value();
}
/**
* Annotation for specifying audit details
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditDetail {
/**
* Name of the audit detail field
*/
String value();
}Usage Examples:
import io.cdap.cdap.common.security.*;
// Method-level authorization
@Path("/api/v1/namespaces/{namespace}")
public class NamespaceHandler {
@GET
@Path("/applications")
@AuthEnforce("namespace:{namespace}")
@AuditPolicy("APPLICATION_LIST")
public void listApplications(@PathParam("namespace") @AuditDetail("namespace") String namespace,
HttpRequest request, HttpResponder responder) {
// This method requires authorization for the specified namespace
// and will be audited with the APPLICATION_LIST policy
List<Application> apps = applicationService.listApplications(namespace);
responder.sendJson(HttpResponseStatus.OK, apps);
}
@DELETE
@Path("/applications/{app}")
@AuthEnforce({"namespace:{namespace}", "application:{app}"})
@AuditPolicy("APPLICATION_DELETE")
public void deleteApplication(@PathParam("namespace") @AuditDetail("namespace") String namespace,
@PathParam("app") @AuditDetail("application") String appName,
HttpRequest request, HttpResponder responder) {
// Requires authorization for both namespace and application
applicationService.deleteApplication(namespace, appName);
responder.sendStatus(HttpResponseStatus.OK);
}
}
// Class-level authorization
@AuthEnforce("admin")
@AuditPolicy("ADMIN_OPERATION")
@Path("/admin")
public class AdminHandler {
@POST
@Path("/reset")
public void resetSystem(HttpRequest request, HttpResponder responder) {
// All methods in this class require admin authorization
systemService.reset();
responder.sendStatus(HttpResponseStatus.OK);
}
}Utilities for SSL/TLS configuration and keystore management.
/**
* KeyStore management utilities
*/
public class KeyStores {
/**
* Generate a self-signed certificate keystore
*/
public static KeyStore generatedCertKeyStore(SConfiguration sConf, String password)
throws GeneralSecurityException, IOException;
/**
* Load keystore from file
*/
public static KeyStore load(File keystoreFile, String password, String type)
throws GeneralSecurityException, IOException;
/**
* Create empty keystore of specified type
*/
public static KeyStore createEmpty(String type) throws GeneralSecurityException;
/**
* Get certificate from keystore
*/
public static Certificate getCertificate(KeyStore keyStore, String alias)
throws KeyStoreException;
}
/**
* HTTPS configuration enabler
*/
public class HttpsEnabler {
/**
* Enable HTTPS for the given configuration
*/
public static void enable(CConfiguration cConf, SConfiguration sConf);
/**
* Check if HTTPS is enabled in configuration
*/
public static boolean isEnabled(CConfiguration cConf);
/**
* Get SSL context from configuration
*/
public static SSLContext getSSLContext(CConfiguration cConf, SConfiguration sConf)
throws GeneralSecurityException, IOException;
}Utilities for managing YARN delegation tokens in secure environments.
/**
* YARN delegation token utilities
*/
public class YarnTokenUtils {
/**
* Obtain delegation tokens for YARN services
*/
public static Credentials obtainTokens(Configuration yarnConf, Credentials credentials)
throws IOException, InterruptedException;
/**
* Add delegation tokens to user credentials
*/
public static void addTokens(Configuration yarnConf, Credentials credentials,
String user, File tokenFile) throws IOException;
/**
* Write tokens to file
*/
public static void writeTokens(Credentials credentials, File tokenFile) throws IOException;
/**
* Read tokens from file
*/
public static Credentials readTokens(File tokenFile) throws IOException;
/**
* Check if tokens are valid and not expired
*/
public static boolean areTokensValid(Credentials credentials);
}Utilities for programmatic authorization enforcement.
/**
* Authorization enforcement utilities
*/
public class AuthEnforceUtil {
/**
* Extract authorization entities from method annotations
*/
public static Set<String> getAuthorizeEntities(Method method, Object[] args);
/**
* Check if method requires authorization
*/
public static boolean requiresAuthorization(Method method);
/**
* Get audit policy from method or class annotations
*/
public static String getAuditPolicy(Method method, Class<?> clazz);
/**
* Extract audit details from method parameters
*/
public static Map<String, String> getAuditDetails(Method method, Object[] args);
/**
* Resolve entity patterns with actual parameter values
*/
public static Set<String> resolveEntityPatterns(String[] patterns,
Method method, Object[] args);
}Advanced Usage Examples:
import io.cdap.cdap.common.security.*;
import javax.net.ssl.SSLContext;
import java.security.KeyStore;
// SSL/TLS configuration
public class SecureServiceConfig {
private final CConfiguration cConf;
private final SConfiguration sConf;
public SecureServiceConfig(CConfiguration cConf, SConfiguration sConf) {
this.cConf = cConf;
this.sConf = sConf;
}
public void configureSSL() throws Exception {
if (HttpsEnabler.isEnabled(cConf)) {
// Generate or load keystore
String keystorePassword = sConf.get("ssl.keystore.password", "changeit");
KeyStore keyStore = KeyStores.generatedCertKeyStore(sConf, keystorePassword);
// Get SSL context
SSLContext sslContext = HttpsEnabler.getSSLContext(cConf, sConf);
// Configure SSL for services
configureServiceSSL(sslContext, keyStore);
}
}
private void configureServiceSSL(SSLContext sslContext, KeyStore keyStore) {
// Configure SSL settings for Netty services, etc.
}
}
// YARN security integration
public class SecureYarnClient {
public void setupSecureClient(Configuration yarnConf, String user) throws Exception {
Credentials credentials = new Credentials();
// Obtain delegation tokens
YarnTokenUtils.obtainTokens(yarnConf, credentials);
// Write tokens to file for secure access
File tokenFile = new File("/tmp/yarn-tokens");
YarnTokenUtils.writeTokens(credentials, tokenFile);
// Add tokens to user credentials
YarnTokenUtils.addTokens(yarnConf, credentials, user, tokenFile);
// Check token validity
if (!YarnTokenUtils.areTokensValid(credentials)) {
System.out.println("Warning: Some tokens may be expired");
}
}
public void refreshTokens(Configuration yarnConf, File tokenFile) throws Exception {
// Read existing tokens
Credentials existing = YarnTokenUtils.readTokens(tokenFile);
if (!YarnTokenUtils.areTokensValid(existing)) {
// Obtain fresh tokens
Credentials fresh = YarnTokenUtils.obtainTokens(yarnConf, new Credentials());
YarnTokenUtils.writeTokens(fresh, tokenFile);
}
}
}
// Authorization enforcement
public class SecurityEnforcer {
public void enforceAuthorization(Method method, Object[] args,
AuthorizationContext authContext) throws ForbiddenException {
if (!AuthEnforceUtil.requiresAuthorization(method)) {
return; // No authorization required
}
// Get entities to authorize
Set<String> entities = AuthEnforceUtil.getAuthorizeEntities(method, args);
// Check authorization for each entity
for (String entity : entities) {
if (!authContext.isAuthorized(entity)) {
throw new ForbiddenException("Not authorized for entity: " + entity);
}
}
}
public void auditMethodCall(Method method, Object[] args, String user) {
String auditPolicy = AuthEnforceUtil.getAuditPolicy(method, method.getDeclaringClass());
if (auditPolicy != null) {
Map<String, String> auditDetails = AuthEnforceUtil.getAuditDetails(method, args);
auditDetails.put("user", user);
auditDetails.put("method", method.getName());
// Log audit event
auditLogger.log(auditPolicy, auditDetails);
}
}
}
// Custom authorization aspect/interceptor
public class AuthorizationInterceptor implements MethodInterceptor {
private final SecurityEnforcer securityEnforcer;
private final AuthorizationContext authContext;
public AuthorizationInterceptor(SecurityEnforcer securityEnforcer,
AuthorizationContext authContext) {
this.securityEnforcer = securityEnforcer;
this.authContext = authContext;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
// Enforce authorization
securityEnforcer.enforceAuthorization(method, args, authContext);
// Audit the method call
String user = authContext.getPrincipal().getName();
securityEnforcer.auditMethodCall(method, args, user);
// Proceed with method execution
return invocation.proceed();
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-cdap-cdap--cdap-common