The security components provide SASL-based authentication for secure communication between shuffle clients and external shuffle services. This ensures that only authorized clients can access shuffle data.
public class ShuffleSecretManager implements SecretKeyHolder {
public ShuffleSecretManager();
public void registerApp(String appId, String shuffleSecret);
public void unregisterApp(String appId);
public String getSecretKey(String appId);
public String getSaslUser(String appId);
}Manages SASL secrets used by the external shuffle service for authenticating client connections.
Key Methods:
Registers a Spark application with its associated secret key for SASL authentication.
Parameters:
appId (String): Spark application identifiershuffleSecret (String): Secret key for SASL authenticationRemoves an application's secret when the application completes or is no longer active.
Parameters:
appId (String): Application identifier to unregisterRetrieves the secret key for a given application. Used during SASL authentication.
Parameters:
appId (String): Application identifierReturns:
String: Secret key for the application, or null if not registeredGets the SASL username for an application. Returns the standard Spark SASL user.
Parameters:
appId (String): Application identifierReturns:
String: SASL username (typically "sparkSaslUser")import org.apache.spark.network.sasl.SecretKeyHolder;
import org.apache.spark.network.shuffle.ExternalShuffleClient;
// Create secret key holder
SecretKeyHolder secretHolder = new SecretKeyHolder() {
@Override
public String getSaslUser(String appId) {
return "sparkSaslUser";
}
@Override
public String getSecretKey(String appId) {
return "my-app-secret-key";
}
};
// Create client with SASL enabled
ExternalShuffleClient client = new ExternalShuffleClient(
conf,
secretHolder,
true, // Enable SASL
true // Enable SASL encryption
);The shuffle service uses ShuffleSecretManager to validate client authentication:
// Create secret manager
ShuffleSecretManager secretManager = new ShuffleSecretManager();
// Register application secrets (typically done by Spark driver)
secretManager.registerApp("app-123", "shared-secret-key");
// Use with SASL-enabled transport context
// (Integration with TransportContext and SaslServerBootstrap)SASL Authentication Process:
ShuffleSecretManagerimport org.apache.spark.network.sasl.ShuffleSecretManager;
// Server-side: Create and configure secret manager
ShuffleSecretManager secretManager = new ShuffleSecretManager();
// Register applications (typically done by Spark driver)
secretManager.registerApp("spark-app-1", "secret-1");
secretManager.registerApp("spark-app-2", "secret-2");
// Later, validate authentication
String secret = secretManager.getSecretKey("spark-app-1");
if (secret != null) {
System.out.println("Application is registered");
} else {
System.out.println("Unknown application");
}// Client-side: Implement SecretKeyHolder
class AppSecretHolder implements SecretKeyHolder {
private final String appSecret;
public AppSecretHolder(String secret) {
this.appSecret = secret;
}
@Override
public String getSaslUser(String appId) {
return "sparkSaslUser"; // Standard Spark SASL user
}
@Override
public String getSecretKey(String appId) {
return appSecret;
}
}
// Create authenticated client
AppSecretHolder secretHolder = new AppSecretHolder("my-app-secret");
ExternalShuffleClient client = new ExternalShuffleClient(
conf,
secretHolder,
true, // SASL enabled
false // SASL encryption disabled for performance
);
client.init("spark-app-1");// Maximum security configuration
ExternalShuffleClient secureClient = new ExternalShuffleClient(
conf,
secretHolder,
true, // Enable SASL authentication
true // Enable SASL encryption
);
// This client will:
// 1. Authenticate using SASL DIGEST-MD5
// 2. Encrypt all data in transit
// 3. Validate server identity// Application startup
secretManager.registerApp("new-app", generateSecret());
try {
// Application runs...
// Shuffle operations proceed with authentication
} finally {
// Application cleanup
secretManager.unregisterApp("new-app");
}import java.security.SecureRandom;
import java.util.Base64;
// Generate secure random secret
SecureRandom random = new SecureRandom();
byte[] secretBytes = new byte[32];
random.nextBytes(secretBytes);
String secret = Base64.getEncoder().encodeToString(secretBytes);
secretManager.registerApp("app-id", secret);Common security-related errors:
// Authentication failure handling
try {
client.fetchBlocks(host, port, execId, blockIds, listener);
} catch (SecurityException e) {
System.err.println("Authentication failed: " + e.getMessage());
// Handle authentication failure:
// - Check secret configuration
// - Verify application registration
// - Retry with updated credentials
}
// SASL configuration errors
try {
client.init("app-id");
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("SASL")) {
System.err.println("SASL configuration error: " + e.getMessage());
// Check SASL settings and secret holder configuration
}
}Authentication Failures
SASL Configuration Errors
Network Connectivity
// Enable SASL debugging (add to JVM arguments)
// -Djava.security.debug=gssloginconfig,configfile,configparser,logincontext
// Enable Spark network debugging
// spark.network.crypto.enabled=true (for additional encryption)
// spark.authenticate=true (for Spark internal authentication)The shuffle service security integrates with Spark's overall security framework: