Skip to content

Commit ecd51df

Browse files
committed
[PLAT-16290] Fix the KMS token renew logic for 70% TTL
Summary: This diff fixes 2 tickets: 1. [PLAT-16290] Fix the KMS token renew logic for 70% TTL . 2. [PLAT-16209] Refresh KMS token every 1 hour via YBA backend Test Plan: Manually tested that the logic works to renew the token after reaching 70%. Tested with 1 min scheduler and 15 min ttl token. Also run UTs. Run itests. Reviewers: vkumar Reviewed By: vkumar Differential Revision: https://phorge.dev.yugabyte.com/D42652
1 parent 93f39ed commit ecd51df

File tree

6 files changed

+71
-7
lines changed

6 files changed

+71
-7
lines changed

managed/RUNTIME-FLAGS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
| "Shell Output Max Directory Size" | "yb.logs.shell.output_dir_max_size" | "GLOBAL" | "Output logs for shell commands are written to tmp folder.This setting defines rotation policy based on directory size." | "Bytes" |
9494
| "Max Size of each log message" | "yb.logs.max_msg_size" | "GLOBAL" | "We limit the length of each log line as sometimes we dump entire output of script. If you want to debug something specific and the script output isgetting truncated in application log then increase this limit" | "Bytes" |
9595
| "KMS Refresh Interval" | "yb.kms.refresh_interval" | "GLOBAL" | "Default refresh interval for the KMS providers." | "Duration" |
96+
| "Percentage of Hashicorp vault TTL to renew the token after" | "yb.kms.hcv_token_renew_percent" | "GLOBAL" | "HashiCorp Vault tokens expire when their TTL is reached. This setting renews the token after it has used the specified percentage of its original TTL. Default: 70%." | "Integer" |
9697
| "Start Master On Stop Node" | "yb.start_master_on_stop_node" | "GLOBAL" | "Auto-start master process on a similar available node on stopping a master node" | "Boolean" |
9798
| "Start Master On Remove Node" | "yb.start_master_on_remove_node" | "GLOBAL" | "Auto-start master process on a similar available node on removal of a master node" | "Boolean" |
9899
| "Server certificate verification for LDAPs/LDAP-TLS" | "yb.security.ldap.enforce_server_cert_verification" | "GLOBAL" | "Enforce server certificate verification for LDAPs/LDAP-TLS" | "Boolean" |

managed/src/main/java/com/yugabyte/yw/common/config/GlobalConfKeys.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,15 @@ public class GlobalConfKeys extends RuntimeConfigKeysModule {
477477
"Allow the usage of CipherTrust KMS.",
478478
ConfDataType.BooleanType,
479479
ImmutableList.of(ConfKeyTags.INTERNAL));
480+
public static final ConfKeyInfo<Integer> hcvTokenRenewPercent =
481+
new ConfKeyInfo<>(
482+
"yb.kms.hcv_token_renew_percent",
483+
ScopeType.GLOBAL,
484+
"Percentage of Hashicorp vault TTL to renew the token after",
485+
"HashiCorp Vault tokens expire when their TTL is reached. This setting renews the token"
486+
+ " after it has used the specified percentage of its original TTL. Default: 70%.",
487+
ConfDataType.IntegerType,
488+
ImmutableList.of(ConfKeyTags.PUBLIC));
480489
// TODO() Add metadata
481490
public static final ConfKeyInfo<Boolean> startMasterOnStopNode =
482491
new ConfKeyInfo<>(

managed/src/main/java/com/yugabyte/yw/common/config/RuntimeConfigPreChangeNotifier.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.yugabyte.yw.common.PlatformServiceException;
1616
import com.yugabyte.yw.common.config.impl.DbAuditLoggingEnabledValidator;
1717
import com.yugabyte.yw.common.config.impl.EnableRollbackSupportKeyValidator;
18+
import com.yugabyte.yw.common.config.impl.HcvTokenRenewPercentValidator;
1819
import com.yugabyte.yw.common.config.impl.MetricCollectionLevelValidator;
1920
import com.yugabyte.yw.common.config.impl.OidcEnabledKeyValidator;
2021
import com.yugabyte.yw.common.config.impl.SSH2EnabledKeyValidator;
@@ -50,13 +51,15 @@ public RuntimeConfigPreChangeNotifier(
5051
UseNewRbacAuthzValidator useNewRbacAuthzValidator,
5152
EnableRollbackSupportKeyValidator enableRollbackSupportKeyValidator,
5253
OidcEnabledKeyValidator oidcEnabledKeyValidator,
53-
DbAuditLoggingEnabledValidator dbAuditLoggingEnabledValidator) {
54+
DbAuditLoggingEnabledValidator dbAuditLoggingEnabledValidator,
55+
HcvTokenRenewPercentValidator hcvTokenRenewPercentValidator) {
5456
addListener(ssh2EnabledKeyValidator);
5557
addListener(metricCollectionLevelValidator);
5658
addListener(useNewRbacAuthzValidator);
5759
addListener(enableRollbackSupportKeyValidator);
5860
addListener(oidcEnabledKeyValidator);
5961
addListener(dbAuditLoggingEnabledValidator);
62+
addListener(hcvTokenRenewPercentValidator);
6063
}
6164

6265
public void notifyListenersDeleteConfig(UUID scopeUUID, String path) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2023 YugaByte, Inc. and Contributors
3+
*
4+
* Licensed under the Polyform Free Trial License 1.0.0 (the "License"); you
5+
* may not use this file except in compliance with the License. You
6+
* may obtain a copy of the License at
7+
*
8+
* http://github.com/YugaByte/yugabyte-db/blob/master/licenses/POLYFORM-FREE-TRIAL-LICENSE-1.0.0.txt
9+
*/
10+
package com.yugabyte.yw.common.config.impl;
11+
12+
import static play.mvc.Http.Status.BAD_REQUEST;
13+
14+
import com.yugabyte.yw.common.PlatformServiceException;
15+
import com.yugabyte.yw.common.config.GlobalConfKeys;
16+
import com.yugabyte.yw.common.config.RuntimeConfigPreChangeValidator;
17+
import java.util.UUID;
18+
import javax.inject.Singleton;
19+
20+
@Singleton
21+
public class HcvTokenRenewPercentValidator implements RuntimeConfigPreChangeValidator {
22+
public String getKeyPath() {
23+
return GlobalConfKeys.hcvTokenRenewPercent.getKey();
24+
}
25+
26+
@Override
27+
public void validateConfigGlobal(UUID scopeUUID, String path, String newValue) {
28+
Integer newValueInt = Integer.parseInt(newValue);
29+
30+
// Check that the runtime config value is between 0 and 100.
31+
if (newValueInt == null || newValueInt <= 0 || newValueInt >= 100) {
32+
throw new PlatformServiceException(
33+
BAD_REQUEST, "HCV token renew percent must be between 0 and 100.");
34+
}
35+
}
36+
}

managed/src/main/java/com/yugabyte/yw/common/kms/util/hashicorpvault/VaultAccessor.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import com.bettercloud.vault.rest.RestResponse;
2222
import com.yugabyte.yw.common.Util;
2323
import com.yugabyte.yw.common.certmgmt.castore.CustomCAStoreManager;
24+
import com.yugabyte.yw.common.config.GlobalConfKeys;
25+
import com.yugabyte.yw.common.config.RuntimeConfGetter;
2426
import com.yugabyte.yw.common.inject.StaticInjectorHolder;
2527
import com.yugabyte.yw.models.helpers.CommonUtils;
2628
import io.ebean.annotation.EnumValue;
@@ -43,7 +45,6 @@ public class VaultAccessor {
4345
public static final Logger LOG = LoggerFactory.getLogger(VaultAccessor.class);
4446

4547
public static final long TTL_RENEWAL_BEFORE_EXPIRY_HRS = 24;
46-
public static final long TTL_EXPIRY_PERCENT_FACTOR = 7; // => x*10%, i.e., if 7 then 70%.
4748

4849
private Vault vault;
4950
private long tokenTTL;
@@ -271,6 +272,14 @@ public List<Object> getTokenExpiryFromVault() throws VaultException {
271272
return Arrays.asList(tokenTTL, tokenTtlExpiry.getTimeInMillis());
272273
}
273274

275+
public int getTokenRenewPercent() {
276+
RuntimeConfGetter runtimeConfGetter =
277+
StaticInjectorHolder.injector().instanceOf(RuntimeConfGetter.class);
278+
Integer hcvTokenRenewPercent =
279+
runtimeConfGetter.getGlobalConf().getInt(GlobalConfKeys.hcvTokenRenewPercent.getKey());
280+
return hcvTokenRenewPercent;
281+
}
282+
274283
/** This is done as best effort, and no guarantees are given at this point of time. */
275284
public void renewSelf() {
276285
try {
@@ -302,12 +311,17 @@ public void renewToken(String token) {
302311
}
303312

304313
long maxttl = vault.auth().lookupSelf().getCreationTTL();
305-
if ((ttl * TTL_EXPIRY_PERCENT_FACTOR) < maxttl) {
314+
LOG.debug("Token {} has ttl: '{}' and creation ttl: '{}'", token, ttl, maxttl);
315+
float hcvTokenRenewPercent = getTokenRenewPercent();
316+
if ((ttl * 100) <= maxttl * (100 - hcvTokenRenewPercent)) {
306317
vault.auth().renewSelf();
307318
LOG.info(
308-
"Token {} is renewed as it has passed {}0% of its expiry window",
309-
token, TTL_EXPIRY_PERCENT_FACTOR);
310-
} else LOG.debug("No need to renew token {} for now", token);
319+
"Token {} is renewed as it has passed {}% of its expiry window",
320+
token, hcvTokenRenewPercent);
321+
} else
322+
LOG.debug(
323+
"No need to renew token {} for now, since token renew percent is '{}'%",
324+
token, hcvTokenRenewPercent);
311325

312326
} catch (VaultException e) {
313327
LOG.warn("Received exception while attempting to renew");

managed/src/main/resources/reference.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1381,8 +1381,9 @@ yb {
13811381
}
13821382

13831383
kms {
1384-
refresh_interval = 12 hours
1384+
refresh_interval = 1 hour
13851385
allow_ciphertrust = false
1386+
hcv_token_renew_percent = 70
13861387
}
13871388

13881389
api {

0 commit comments

Comments
 (0)