diff --git a/common/protocols/src/main/proto/app/coronawarn/server/common/protocols/internal/app_config.proto b/common/protocols/src/main/proto/app/coronawarn/server/common/protocols/internal/app_config.proto
--- a/common/protocols/src/main/proto/app/coronawarn/server/common/protocols/internal/app_config.proto
+++ b/common/protocols/src/main/proto/app/coronawarn/server/common/protocols/internal/app_config.proto
@@ -5,6 +5,7 @@ option java_multiple_files = true;
 import "app/coronawarn/server/common/protocols/internal/risk_score_classification.proto";
 import "app/coronawarn/server/common/protocols/internal/risk_score_parameters.proto";
 import "app/coronawarn/server/common/protocols/internal/app_version_config.proto";
+import "app/coronawarn/server/common/protocols/internal/attenuation_duration.proto";

 message ApplicationConfiguration {

@@ -14,12 +15,7 @@ message ApplicationConfiguration {

   app.coronawarn.server.common.protocols.internal.RiskScoreParameters exposureConfig = 3;

-  AttenuationDurationThresholds attenuationDurationThresholds = 4;
+  app.coronawarn.server.common.protocols.internal.AttenuationDuration attenuationDuration = 4;

   app.coronawarn.server.common.protocols.internal.ApplicationVersionConfiguration appVersion = 5;
 }
-
-message AttenuationDurationThresholds {
-  int32 lower = 1;
-  int32 upper = 2;
-}
\ No newline at end of file
diff --git a/common/protocols/src/main/proto/app/coronawarn/server/common/protocols/internal/attenuation_duration.proto b/common/protocols/src/main/proto/app/coronawarn/server/common/protocols/internal/attenuation_duration.proto
new file mode 100644
--- /dev/null
+++ b/common/protocols/src/main/proto/app/coronawarn/server/common/protocols/internal/attenuation_duration.proto
@@ -0,0 +1,20 @@
+syntax = "proto3";
+package app.coronawarn.server.common.protocols.internal;
+option java_package = "app.coronawarn.server.common.protocols.internal";
+option java_multiple_files = true;
+
+message AttenuationDuration {
+  Thresholds thresholds = 1;
+  Weights weights = 2;
+}
+
+message Thresholds {
+  int32 lower = 1;
+  int32 upper = 2;
+}
+
+message Weights {
+  double low = 1;
+  double mid = 2;
+  double high = 3;
+}
diff --git a/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidator.java b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidator.java
--- a/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidator.java
+++ b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidator.java
@@ -20,11 +20,6 @@

 package app.coronawarn.server.services.distribution.assembly.appconfig.validation;

-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.MIN_GREATER_THAN_MAX;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.VALUE_OUT_OF_BOUNDS;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MAX;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MIN;
-
 import app.coronawarn.server.common.protocols.internal.ApplicationConfiguration;
 import app.coronawarn.server.common.protocols.internal.RiskScoreClassification;
 import app.coronawarn.server.common.protocols.internal.RiskScoreParameters;
@@ -51,12 +46,13 @@ public ValidationResult validate() {
     this.errors = new ValidationResult();

     validateMinRisk();
-    validateAttenuationDurationThresholds();

-    ValidationResult exposureResult = new ExposureConfigurationValidator(config.getExposureConfig()).validate();
-    ValidationResult riskScoreResult = new RiskScoreClassificationValidator(config.getRiskScoreClasses()).validate();
+    errors.with(new ExposureConfigurationValidator(config.getExposureConfig()).validate());
+    errors.with(new RiskScoreClassificationValidator(config.getRiskScoreClasses()).validate());
+    errors.with(new ApplicationVersionConfigurationValidator(config.getAppVersion()).validate());
+    errors.with(new AttenuationDurationValidator(config.getAttenuationDuration()).validate());

-    return errors.with(exposureResult).with(riskScoreResult);
+    return errors;
   }

   private void validateMinRisk() {
@@ -66,25 +62,4 @@ private void validateMinRisk() {
       this.errors.add(new MinimumRiskLevelValidationError(minLevel));
     }
   }
-
-  private void validateAttenuationDurationThresholds() {
-    int lower = config.getAttenuationDurationThresholds().getLower();
-    int upper = config.getAttenuationDurationThresholds().getUpper();
-
-    checkThresholdBound("lower", lower);
-    checkThresholdBound("upper", upper);
-
-    if (lower > upper) {
-      String parameters = "attenuationDurationThreshold.lower, attenuationDurationThreshold.upper";
-      String values = lower + ", " + upper;
-      this.errors.add(new GeneralValidationError(parameters, values, MIN_GREATER_THAN_MAX));
-    }
-  }
-
-  private void checkThresholdBound(String boundLabel, int boundValue) {
-    if (boundValue < ATTENUATION_DURATION_THRESHOLD_MIN || boundValue > ATTENUATION_DURATION_THRESHOLD_MAX) {
-      this.errors.add(
-          new GeneralValidationError("attenuationDurationThreshold." + boundLabel, boundValue, VALUE_OUT_OF_BOUNDS));
-    }
-  }
 }
diff --git a/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/AttenuationDurationValidator.java b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/AttenuationDurationValidator.java
new file mode 100644
--- /dev/null
+++ b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/AttenuationDurationValidator.java
@@ -0,0 +1,94 @@
+/*-
+ * ---license-start
+ * Corona-Warn-App
+ * ---
+ * Copyright (C) 2020 SAP SE and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package app.coronawarn.server.services.distribution.assembly.appconfig.validation;
+
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.MIN_GREATER_THAN_MAX;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.VALUE_OUT_OF_BOUNDS;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MAX;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MIN;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_WEIGHT_MAX;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_WEIGHT_MIN;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.WeightValidationError.ErrorType.OUT_OF_RANGE;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.WeightValidationError.ErrorType.TOO_MANY_DECIMAL_PLACES;
+
+import app.coronawarn.server.common.protocols.internal.AttenuationDuration;
+import java.math.BigDecimal;
+
+/**
+ * The AttenuationDurationValidator validates the values of an associated {@link AttenuationDuration} instance.
+ */
+public class AttenuationDurationValidator extends ConfigurationValidator {
+
+  private final AttenuationDuration attenuationDuration;
+
+  public AttenuationDurationValidator(AttenuationDuration attenuationDuration) {
+    this.attenuationDuration = attenuationDuration;
+  }
+
+  @Override
+  public ValidationResult validate() {
+    errors = new ValidationResult();
+
+    validateThresholds();
+    validateWeights();
+
+    return errors;
+  }
+
+  private void validateThresholds() {
+    int lower = attenuationDuration.getThresholds().getLower();
+    int upper = attenuationDuration.getThresholds().getUpper();
+
+    checkThresholdBound("lower", lower);
+    checkThresholdBound("upper", upper);
+
+    if (lower > upper) {
+      String parameters = "attenuation-duration.thresholds.lower, attenuation-duration.thresholds.upper";
+      String values = lower + ", " + upper;
+      this.errors.add(new GeneralValidationError(parameters, values, MIN_GREATER_THAN_MAX));
+    }
+  }
+
+  private void checkThresholdBound(String thresholdLabel, int thresholdValue) {
+    if (thresholdValue < ATTENUATION_DURATION_THRESHOLD_MIN || thresholdValue > ATTENUATION_DURATION_THRESHOLD_MAX) {
+      this.errors.add(new GeneralValidationError(
+          "attenuation-duration.thresholds." + thresholdLabel, thresholdValue, VALUE_OUT_OF_BOUNDS));
+    }
+  }
+
+  private void validateWeights() {
+    checkWeight("low", attenuationDuration.getWeights().getLow());
+    checkWeight("mid", attenuationDuration.getWeights().getMid());
+    checkWeight("high", attenuationDuration.getWeights().getHigh());
+  }
+
+  private void checkWeight(String weightLabel, double weightValue) {
+    if (weightValue < ATTENUATION_DURATION_WEIGHT_MIN || weightValue > ATTENUATION_DURATION_WEIGHT_MAX) {
+      this.errors.add(new WeightValidationError(
+          "attenuation-duration.weights." + weightLabel, weightValue, OUT_OF_RANGE));
+    }
+
+    if (BigDecimal.valueOf(weightValue).scale() > ParameterSpec.ATTENUATION_DURATION_WEIGHT_MAX_DECIMALS) {
+      this.errors.add(new WeightValidationError(
+          "attenuation-duration.weights." + weightLabel, weightValue, TOO_MANY_DECIMAL_PLACES));
+    }
+  }
+}
diff --git a/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ParameterSpec.java b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ParameterSpec.java
--- a/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ParameterSpec.java
+++ b/services/distribution/src/main/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ParameterSpec.java
@@ -63,4 +63,19 @@ private ParameterSpec() {
    * The allowed maximum value for an attenuation threshold.
    */
   public static final int ATTENUATION_DURATION_THRESHOLD_MAX = 100;
+
+  /**
+   * The allowed minimum value for an attenuation weight.
+   */
+  public static final double ATTENUATION_DURATION_WEIGHT_MIN = .0;
+
+  /**
+   * The allowed maximum value for an attenuation weight.
+   */
+  public static final double ATTENUATION_DURATION_WEIGHT_MAX = 1.;
+
+  /**
+   * Maximum number of allowed decimals for an attenuation weight.
+   */
+  public static final int ATTENUATION_DURATION_WEIGHT_MAX_DECIMALS = 3;
 }
diff --git a/services/distribution/src/main/resources/master-config/app-config.yaml b/services/distribution/src/main/resources/master-config/app-config.yaml
--- a/services/distribution/src/main/resources/master-config/app-config.yaml
+++ b/services/distribution/src/main/resources/master-config/app-config.yaml
@@ -9,9 +9,7 @@
 # Change this file with caution!

 min-risk-score: 90
-attenuationDurationThresholds:
-  lower: 50
-  upper: 70
+attenuation-duration: !include attenuation-duration.yaml
 risk-score-classes: !include risk-score-classification.yaml
 exposure-config: !include exposure-config.yaml
-app-version: !include app-version-config.yaml
\ No newline at end of file
+app-version: !include app-version-config.yaml
diff --git a/services/distribution/src/main/resources/master-config/attenuation-duration.yaml b/services/distribution/src/main/resources/master-config/attenuation-duration.yaml
new file mode 100644
--- /dev/null
+++ b/services/distribution/src/main/resources/master-config/attenuation-duration.yaml
@@ -0,0 +1,15 @@
+# This is the attenuation and duration parameter thresholds. The lower and
+# upper threshold partitions the value range into 3 subsets: low, mid, high
+#
+# Each of the aforementioned partitions has a weight in the range of [0, 1]
+# assigned to it. The number of decimal places is restricted to 3.
+#
+# Change this file with caution!
+
+thresholds:
+  lower: 50
+  upper: 70
+weights:
+  low: 1.0
+  mid: 0.5
+  high: 0.0

diff --git a/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/AttenuationDurationMasterFileTest.java b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/AttenuationDurationMasterFileTest.java
new file mode 100644
--- /dev/null
+++ b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/AttenuationDurationMasterFileTest.java
@@ -0,0 +1,47 @@
+/*-
+ * ---license-start
+ * Corona-Warn-App
+ * ---
+ * Copyright (C) 2020 SAP SE and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package app.coronawarn.server.services.distribution.assembly.appconfig;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import app.coronawarn.server.common.protocols.internal.AttenuationDuration;
+import app.coronawarn.server.services.distribution.assembly.appconfig.validation.AttenuationDurationValidator;
+import app.coronawarn.server.services.distribution.assembly.appconfig.validation.ConfigurationValidator;
+import app.coronawarn.server.services.distribution.assembly.appconfig.validation.ValidationResult;
+import org.junit.jupiter.api.Test;
+
+/**
+ * This test will verify that the provided attenuation/duration parameters master file is syntactically correct and
+ * according to spec. There should never be any deployment when this test is failing.
+ */
+class AttenuationDurationMasterFileTest {
+
+  private static final ValidationResult SUCCESS = new ValidationResult();
+
+  @Test
+  void testMasterFile() throws UnableToLoadFileException {
+    AttenuationDuration config = ApplicationConfigurationProvider.readMasterFile().getAttenuationDuration();
+
+    ConfigurationValidator validator = new AttenuationDurationValidator(config);
+
+    assertThat(validator.validate()).isEqualTo(SUCCESS);
+  }
+}
diff --git a/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidatorTest.java b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidatorTest.java
--- a/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidatorTest.java
+++ b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/ApplicationConfigurationValidatorTest.java
@@ -20,26 +20,16 @@

 package app.coronawarn.server.services.distribution.assembly.appconfig.validation;

-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.MIN_GREATER_THAN_MAX;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.VALUE_OUT_OF_BOUNDS;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MAX;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MIN;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.RiskScoreClassificationValidatorTest.MINIMAL_RISK_SCORE_CLASSIFICATION;
-import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.RiskScoreClassificationValidatorTest.buildExpectedResult;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;

-import app.coronawarn.server.common.protocols.internal.ApplicationConfiguration;
-import app.coronawarn.server.common.protocols.internal.AttenuationDurationThresholds;
 import app.coronawarn.server.services.distribution.assembly.appconfig.ApplicationConfigurationProvider;
-import app.coronawarn.server.services.distribution.assembly.appconfig.ExposureConfigurationProvider;
 import app.coronawarn.server.services.distribution.assembly.appconfig.UnableToLoadFileException;
 import java.util.stream.Stream;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
-import org.junit.jupiter.params.provider.ValueSource;

 class ApplicationConfigurationValidatorTest {

@@ -59,43 +49,6 @@ void negative(TestWithExpectedResult test) throws UnableToLoadFileException {
     assertThat(getResultForTest(test)).isEqualTo(test.result);
   }

-  @ParameterizedTest
-  @ValueSource(ints = {ATTENUATION_DURATION_THRESHOLD_MIN - 1, ATTENUATION_DURATION_THRESHOLD_MAX + 1})
-  void negativeForAttenuationDurationThresholdOutOfBounds(int invalidThresholdValue) throws Exception {
-    ApplicationConfigurationValidator validator = getValidatorForAttenuationDurationThreshold(
-        invalidThresholdValue, invalidThresholdValue);
-
-    ValidationResult expectedResult = buildExpectedResult(
-        new GeneralValidationError("attenuationDurationThreshold.upper", invalidThresholdValue, VALUE_OUT_OF_BOUNDS),
-        new GeneralValidationError("attenuationDurationThreshold.lower", invalidThresholdValue, VALUE_OUT_OF_BOUNDS));
-
-    assertThat(validator.validate()).isEqualTo(expectedResult);
-  }
-
-  @Test
-  void negativeForUpperAttenuationDurationThresholdLesserThanLower() throws Exception {
-    ApplicationConfigurationValidator validator = getValidatorForAttenuationDurationThreshold(
-        ATTENUATION_DURATION_THRESHOLD_MAX, ATTENUATION_DURATION_THRESHOLD_MIN);
-
-    ValidationResult expectedResult = buildExpectedResult(
-        new GeneralValidationError("attenuationDurationThreshold.lower, attenuationDurationThreshold.upper",
-            (ATTENUATION_DURATION_THRESHOLD_MAX + ", " + ATTENUATION_DURATION_THRESHOLD_MIN), MIN_GREATER_THAN_MAX));
-
-    assertThat(validator.validate()).isEqualTo(expectedResult);
-  }
-
-  private ApplicationConfigurationValidator getValidatorForAttenuationDurationThreshold(int lower, int upper)
-      throws Exception {
-    ApplicationConfiguration appConfig = ApplicationConfiguration.newBuilder()
-        .setMinRiskScore(100)
-        .setRiskScoreClasses(MINIMAL_RISK_SCORE_CLASSIFICATION)
-        .setExposureConfig(ExposureConfigurationProvider.readFile("configtests/exposure-config_ok.yaml"))
-        .setAttenuationDurationThresholds(AttenuationDurationThresholds.newBuilder()
-            .setLower(lower)
-            .setUpper(upper)).build();
-    return new ApplicationConfigurationValidator(appConfig);
-  }
-
   @Test
   void circular() {
     assertThatThrownBy(() -> {
diff --git a/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/AttenuationDurationValidatorTest.java b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/AttenuationDurationValidatorTest.java
new file mode 100644
--- /dev/null
+++ b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/AttenuationDurationValidatorTest.java
@@ -0,0 +1,114 @@
+/*-
+ * ---license-start
+ * Corona-Warn-App
+ * ---
+ * Copyright (C) 2020 SAP SE and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package app.coronawarn.server.services.distribution.assembly.appconfig.validation;
+
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.MIN_GREATER_THAN_MAX;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.GeneralValidationError.ErrorType.VALUE_OUT_OF_BOUNDS;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MAX;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_THRESHOLD_MIN;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_WEIGHT_MAX;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.ParameterSpec.ATTENUATION_DURATION_WEIGHT_MIN;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.RiskScoreClassificationValidatorTest.buildError;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.RiskScoreClassificationValidatorTest.buildExpectedResult;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.WeightValidationError.ErrorType.OUT_OF_RANGE;
+import static app.coronawarn.server.services.distribution.assembly.appconfig.validation.WeightValidationError.ErrorType.TOO_MANY_DECIMAL_PLACES;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import app.coronawarn.server.common.protocols.internal.AttenuationDuration;
+import app.coronawarn.server.common.protocols.internal.Thresholds;
+import app.coronawarn.server.common.protocols.internal.Weights;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+public class AttenuationDurationValidatorTest {
+  private static final Thresholds VALID_THRESHOLDS =
+      buildThresholds(ATTENUATION_DURATION_THRESHOLD_MIN, ATTENUATION_DURATION_THRESHOLD_MAX);
+  private static final Weights VALID_WEIGHTS =
+      buildWeights(ATTENUATION_DURATION_WEIGHT_MAX, ATTENUATION_DURATION_WEIGHT_MAX, ATTENUATION_DURATION_WEIGHT_MAX);
+
+  @ParameterizedTest
+  @ValueSource(ints = {ATTENUATION_DURATION_THRESHOLD_MIN - 1, ATTENUATION_DURATION_THRESHOLD_MAX + 1})
+  void failsIfAttenuationDurationThresholdOutOfBounds(int invalidThresholdValue) {
+    AttenuationDurationValidator validator = buildValidator(
+        buildThresholds(invalidThresholdValue, invalidThresholdValue), VALID_WEIGHTS);
+
+    ValidationResult expectedResult = buildExpectedResult(
+        buildError("attenuation-duration.thresholds.lower", invalidThresholdValue, VALUE_OUT_OF_BOUNDS),
+        buildError("attenuation-duration.thresholds.upper", invalidThresholdValue, VALUE_OUT_OF_BOUNDS));
+
+    assertThat(validator.validate()).isEqualTo(expectedResult);
+  }
+
+  @Test
+  void failsIfUpperAttenuationDurationThresholdLesserThanLower() {
+    AttenuationDurationValidator validator = buildValidator(
+        buildThresholds(ATTENUATION_DURATION_THRESHOLD_MAX, ATTENUATION_DURATION_THRESHOLD_MIN), VALID_WEIGHTS);
+
+    ValidationResult expectedResult = buildExpectedResult(
+        new GeneralValidationError("attenuation-duration.thresholds.lower, attenuation-duration.thresholds.upper",
+            (ATTENUATION_DURATION_THRESHOLD_MAX + ", " + ATTENUATION_DURATION_THRESHOLD_MIN), MIN_GREATER_THAN_MAX));
+
+    assertThat(validator.validate()).isEqualTo(expectedResult);
+  }
+
+  @ParameterizedTest
+  @ValueSource(doubles = {ATTENUATION_DURATION_WEIGHT_MIN - .1, ATTENUATION_DURATION_WEIGHT_MAX + .1})
+  void failsIfWeightsOutOfBounds(double invalidWeightValue) {
+    AttenuationDurationValidator validator = buildValidator(VALID_THRESHOLDS,
+        buildWeights(invalidWeightValue, invalidWeightValue, invalidWeightValue));
+
+    ValidationResult expectedResult = buildExpectedResult(
+        new WeightValidationError("attenuation-duration.weights.low", invalidWeightValue, OUT_OF_RANGE),
+        new WeightValidationError("attenuation-duration.weights.mid", invalidWeightValue, OUT_OF_RANGE),
+        new WeightValidationError("attenuation-duration.weights.high", invalidWeightValue, OUT_OF_RANGE));
+
+    assertThat(validator.validate()).isEqualTo(expectedResult);
+  }
+
+  @Test
+  void failsIfWeightsHaveTooManyDecimalPlaces() {
+    double invalidWeightValue = ATTENUATION_DURATION_WEIGHT_MAX - 0.0000001;
+    AttenuationDurationValidator validator = buildValidator(VALID_THRESHOLDS,
+        buildWeights(invalidWeightValue, invalidWeightValue, invalidWeightValue));
+
+    ValidationResult expectedResult = buildExpectedResult(
+        new WeightValidationError("attenuation-duration.weights.low", invalidWeightValue, TOO_MANY_DECIMAL_PLACES),
+        new WeightValidationError("attenuation-duration.weights.mid", invalidWeightValue, TOO_MANY_DECIMAL_PLACES),
+        new WeightValidationError("attenuation-duration.weights.high", invalidWeightValue, TOO_MANY_DECIMAL_PLACES));
+
+    assertThat(validator.validate()).isEqualTo(expectedResult);
+  }
+
+  private static AttenuationDurationValidator buildValidator(Thresholds thresholds, Weights weights) {
+    return new AttenuationDurationValidator(AttenuationDuration.newBuilder()
+        .setThresholds(thresholds)
+        .setWeights(weights).build());
+  }
+
+  private static Thresholds buildThresholds(int lower, int upper) {
+    return Thresholds.newBuilder().setLower(lower).setUpper(upper).build();
+  }
+
+  private static Weights buildWeights(double low, double mid, double high) {
+    return Weights.newBuilder().setLow(low).setMid(mid).setHigh(high).build();
+  }
+}
diff --git a/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/RiskScoreClassificationValidatorTest.java b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/RiskScoreClassificationValidatorTest.java
--- a/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/RiskScoreClassificationValidatorTest.java
+++ b/services/distribution/src/test/java/app/coronawarn/server/services/distribution/assembly/appconfig/validation/RiskScoreClassificationValidatorTest.java
@@ -166,7 +166,7 @@ private static RiskScoreClass buildRiskClass(String label, int min, int max, Str
     return RiskScoreClass.newBuilder().setLabel(label).setMin(min).setMax(max).setUrl(url).build();
   }

-  public static ValidationResult buildExpectedResult(GeneralValidationError... errors) {
+  public static ValidationResult buildExpectedResult(ValidationError... errors) {
     var validationResult = new ValidationResult();
     Arrays.stream(errors).forEach(validationResult::add);
     return validationResult;
diff --git a/services/distribution/src/test/resources/configtests/app-config_ok.yaml b/services/distribution/src/test/resources/configtests/app-config_ok.yaml
--- a/services/distribution/src/test/resources/configtests/app-config_ok.yaml
+++ b/services/distribution/src/test/resources/configtests/app-config_ok.yaml
@@ -1,7 +1,5 @@
 min-risk-score: 100
-attenuationDurationThresholds:
-  lower: 50
-  upper: 70
+attenuation-duration: !include attenuation-duration.yaml
 risk-score-classes: !include risk-score-class_ok.yaml
 exposure-config: !include exposure-config_ok.yaml
-app-version: !include app-version-config_ok.yaml
\ No newline at end of file
+app-version: !include app-version-config_ok.yaml
diff --git a/services/distribution/src/test/resources/configtests/attenuation-duration.yaml b/services/distribution/src/test/resources/configtests/attenuation-duration.yaml
new file mode 100644
--- /dev/null
+++ b/services/distribution/src/test/resources/configtests/attenuation-duration.yaml
@@ -0,0 +1,7 @@
+thresholds:
+  lower: 50
+  upper: 70
+weights:
+  low: 1.0
+  mid: 0.5
+  high: 0.0

Application Configuration: Attenuation Duration
The RKI requested weighting parameters for the three buckets defined by the attenuation duration threshold. Add this to the attenuation duration configuration.

@michael-burwig

```yaml
attenuation-duration:
  thresholds:
    lower: 50
    upper: 70
  weights:
    low: 1 # attenuation < 50 dB
    mid: 0.5 # attenuation >50 dB && < 70 dB
    high: 0 # attenuation > 70dB is ignored
```

Are the weights in the range of [0, 1]?
Is the threshold value range still [0, 100]?
Thresholds remain unchanged.
For weight, lets go with 0...1 for now. There will be another RKI call in the afternoon which might change that though.