Skip to content

Remove remote configuration for API Security sampling rate #8486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,7 @@ private static void doStart(SubscriptionService gw, SharedCommunicationObjects s
// may throw and abort startup
APP_SEC_CONFIG_SERVICE =
new AppSecConfigServiceImpl(
config,
configurationPoller,
requestSampler,
() -> reloadSubscriptions(REPLACEABLE_EVENT_PRODUCER));
config, configurationPoller, () -> reloadSubscriptions(REPLACEABLE_EVENT_PRODUCER));
APP_SEC_CONFIG_SERVICE.init();

sco.createRemaining(config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import static datadog.remoteconfig.Capabilities.CAPABILITY_ENDPOINT_FINGERPRINT;

import com.datadog.appsec.AppSecSystem;
import com.datadog.appsec.api.security.ApiSecurityRequestSampler;
import com.datadog.appsec.config.AppSecModuleConfigurer.SubconfigListener;
import com.datadog.appsec.config.CurrentAppSecConfig.DirtyStatus;
import com.datadog.appsec.util.AbortStartupException;
Expand Down Expand Up @@ -72,7 +71,6 @@ public class AppSecConfigServiceImpl implements AppSecConfigService {
private final Config tracerConfig;
private final List<TraceSegmentPostProcessor> traceSegmentPostProcessors = new ArrayList<>();
private final AppSecModuleConfigurer.Reconfiguration reconfiguration;
private final ApiSecurityRequestSampler apiSecurityRequestSampler;

private final ConfigurationEndListener applyRemoteConfigListener =
this::applyRemoteConfigListener;
Expand All @@ -82,12 +80,10 @@ public class AppSecConfigServiceImpl implements AppSecConfigService {
public AppSecConfigServiceImpl(
Config tracerConfig,
ConfigurationPoller configurationPoller,
ApiSecurityRequestSampler apiSecurityRequestSampler,
AppSecModuleConfigurer.Reconfiguration reconfig) {
this.tracerConfig = tracerConfig;
this.configurationPoller = configurationPoller;
this.reconfiguration = reconfig;
this.apiSecurityRequestSampler = apiSecurityRequestSampler;
}

private void subscribeConfigurationPoller() {
Expand Down Expand Up @@ -385,7 +381,6 @@ private void applyRemoteConfigListener() {
// apply ASM_FEATURES configuration first as they might enable AppSec
final AppSecFeatures features = mergedAsmFeatures.getMergedData();
setAppSecActivation(features.asm);
setApiSecuritySampling(features.apiSecurity);
setUserIdCollectionMode(features.autoUserInstrum);

if (!AppSecSystem.isActive() || !currentAppSecConfig.dirtyStatus.isAnyDirty()) {
Expand Down Expand Up @@ -415,25 +410,6 @@ private void setAppSecActivation(final AppSecFeatures.Asm asm) {
}
}

private void setApiSecuritySampling(final AppSecFeatures.ApiSecurity apiSecurity) {
final float newSampling;
if (apiSecurity == null) {
newSampling = tracerConfig.getApiSecurityRequestSampleRate();
} else {
newSampling = apiSecurity.requestSampleRate;
}
if (apiSecurityRequestSampler.setSampling(newSampling)) {
int pct = apiSecurityRequestSampler.getSampling();
if (pct == 0) {
log.info("Api Security is disabled via remote-config");
} else {
log.info(
"Api Security changed via remote-config. New sampling rate is {}% of all requests.",
pct);
}
}
}

private void setUserIdCollectionMode(final AppSecFeatures.AutoUserInstrum autoUserInstrum) {
UserIdCollectionMode current = UserIdCollectionMode.get();
UserIdCollectionMode newMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
public class AppSecFeatures {
public Asm asm;

@com.squareup.moshi.Json(name = "api_security")
public ApiSecurity apiSecurity;

@com.squareup.moshi.Json(name = "auto_user_instrum")
public AutoUserInstrum autoUserInstrum;

Expand All @@ -18,16 +15,6 @@ public String toString() {
}
}

public static class ApiSecurity {
@com.squareup.moshi.Json(name = "request_sample_rate")
public Float requestSampleRate;

@Override
public String toString() {
return "ApiSecurity{" + "requestSampleRate=" + requestSampleRate + '}';
}
}

public static class AutoUserInstrum {
public String mode;

Expand All @@ -39,13 +26,6 @@ public String toString() {

@Override
public String toString() {
return "AppSecFeatures{"
+ "asm="
+ asm
+ ", apiSecurity="
+ apiSecurity
+ ", autoUserInstrum="
+ autoUserInstrum
+ '}';
return "AppSecFeatures{" + "asm=" + asm + ", autoUserInstrum=" + autoUserInstrum + '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public AppSecFeatures getMergedData() {

private AppSecFeatures merge(final AppSecFeatures target, final AppSecFeatures newFeatures) {
mergeAsm(target, newFeatures.asm);
mergeApiSecurity(target, newFeatures.apiSecurity);
mergeAutoUserInstrum(target, newFeatures.autoUserInstrum);
return target;
}
Expand All @@ -43,14 +42,6 @@ private void mergeAsm(final AppSecFeatures target, final AppSecFeatures.Asm newV
target.asm = newValue;
}

private void mergeApiSecurity(
final AppSecFeatures target, final AppSecFeatures.ApiSecurity newValue) {
if (newValue == null || newValue.requestSampleRate == null) {
return;
}
target.apiSecurity = newValue;
}

private void mergeAutoUserInstrum(
final AppSecFeatures target, final AppSecFeatures.AutoUserInstrum newValue) {
if (newValue == null || newValue.mode == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.datadog.appsec.config

import com.datadog.appsec.AppSecSystem
import com.datadog.appsec.api.security.ApiSecurityRequestSampler
import com.datadog.appsec.util.AbortStartupException
import datadog.remoteconfig.ConfigurationChangesTypedListener
import datadog.remoteconfig.ConfigurationDeserializer
Expand Down Expand Up @@ -45,9 +44,8 @@ class AppSecConfigServiceImplSpecification extends DDSpecification {

ConfigurationPoller poller = Mock()
def config = Mock(Class.forName('datadog.trace.api.Config'))
ApiSecurityRequestSampler sampler = Mock(ApiSecurityRequestSampler)
AppSecModuleConfigurer.Reconfiguration reconf = Stub()
AppSecConfigServiceImpl appSecConfigService = new AppSecConfigServiceImpl(config, poller, sampler, reconf)
AppSecConfigServiceImpl appSecConfigService = new AppSecConfigServiceImpl(config, poller, reconf)

void cleanup() {
appSecConfigService?.close()
Expand Down Expand Up @@ -533,35 +531,6 @@ class AppSecConfigServiceImplSpecification extends DDSpecification {
thrown IOException
}

void 'update sample rate via remote-config'() {
given:
def newConfig = new AppSecFeatures().tap { features ->
features.apiSecurity = new AppSecFeatures.ApiSecurity().tap { api ->
api.requestSampleRate = 0.2
}
}
def listeners = new SavedListeners()

when:
appSecConfigService.init()
appSecConfigService.maybeSubscribeConfigPolling()

then:
1 * poller.addListener(Product.ASM_FEATURES, _, _) >> {
listeners.savedFeaturesDeserializer = it[1]
listeners.savedFeaturesListener = it[2]
}
1 * poller.addCapabilities(CAPABILITY_ASM_API_SECURITY_SAMPLE_RATE)
1 * poller.addConfigurationEndListener(_) >> { listeners.savedConfEndListener = it[0] }

when:
listeners.savedFeaturesListener.accept('asm_api_security', newConfig, null)
listeners.savedConfEndListener.onConfigurationEnd()

then:
1 * sampler.setSampling(0.2F)
}

void 'update auto user instrum mode via remote-config'() {
given:
def listeners = new SavedListeners()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,6 @@ class MergedAsmFeaturesSpecification extends Specification {
features.mergedData.asm.enabled
}

void 'test merging and removing api security sampling'() {
setup:
final features = new MergedAsmFeatures()

when:
features.addConfig('api_security_1', apiSecurity(2.0))

then:
features.mergedData.apiSecurity.requestSampleRate == 2.0

when:
features.addConfig('api_security_1', apiSecurity(3.0))

then:
features.mergedData.apiSecurity.requestSampleRate == 3.0
}

void 'test merging and removing auto user instrum'() {
setup:
final features = new MergedAsmFeatures()
Expand All @@ -63,10 +46,6 @@ class MergedAsmFeaturesSpecification extends Specification {
return new AppSecFeatures(asm: new AppSecFeatures.Asm(enabled: enabled))
}

private static AppSecFeatures apiSecurity(float sampling) {
new AppSecFeatures(apiSecurity: new AppSecFeatures.ApiSecurity(requestSampleRate: sampling))
}

private static AppSecFeatures autoUserInstrum(UserIdCollectionMode mode) {
new AppSecFeatures(autoUserInstrum: new AppSecFeatures.AutoUserInstrum(mode: mode.toString()))
}
Expand Down