diff --git a/.github/workflows/check-remote.yaml b/.github/workflows/check-remote.yaml index d1d41d2..8c3de1d 100644 --- a/.github/workflows/check-remote.yaml +++ b/.github/workflows/check-remote.yaml @@ -56,7 +56,7 @@ jobs: | jq -r .[].tag_name \ | grep -E ".*(v[0-9]*.[0-9]*.[0-9]*).*" \ | sed -e 's/.*v\([0-9]*.[0-9]*.[0-9]*\).*/\1/g' \ - | sort -ru \ + | sort -ruV \ | head -n1 )" TAG_VERSION="$( \ @@ -64,7 +64,7 @@ jobs: | jq -r .[].tag_name \ | grep -E ".*(v[0-9]*.[0-9]*.[0-9]*).*" \ | sed -e 's/.*\(v[0-9]*.[0-9]*.[0-9]*\).*/\1/g' \ - | sort -ru \ + | sort -ruV \ | head -n1 )" fi diff --git a/pom.xml.template b/pom.xml.template index 902166b..98f36ee 100644 --- a/pom.xml.template +++ b/pom.xml.template @@ -3,7 +3,7 @@ 4.0.0 athenz-plugins - Core Auth Interfaces + Athenz Plugin Implementations io.athenz athenz-plugins 0.0.0 diff --git a/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultAWSElasticKubernetesServiceValidator.java b/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultAWSElasticKubernetesServiceValidator.java new file mode 100644 index 0000000..8e6fafc --- /dev/null +++ b/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultAWSElasticKubernetesServiceValidator.java @@ -0,0 +1,231 @@ +package com.yahoo.athenz.instance.provider.impl; + +import com.yahoo.athenz.auth.Authorizer; +import com.yahoo.athenz.auth.Principal; +import com.yahoo.athenz.auth.impl.SimplePrincipal; +import com.yahoo.athenz.common.server.util.config.dynamic.DynamicConfigBoolean; +import com.yahoo.athenz.common.server.util.config.dynamic.DynamicConfigCsv; +import com.yahoo.athenz.instance.provider.AttrValidator; +import com.yahoo.athenz.instance.provider.AttrValidatorFactory; +import com.yahoo.athenz.instance.provider.InstanceConfirmation; +import org.eclipse.jetty.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLContext; +import java.lang.invoke.MethodHandles; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; +import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.sts.StsClient; +import software.amazon.awssdk.services.iam.model.ListOpenIdConnectProvidersRequest; +import software.amazon.awssdk.services.iam.model.ListOpenIdConnectProvidersResponse; +import software.amazon.awssdk.services.iam.model.OpenIDConnectProviderListEntry; +import software.amazon.awssdk.services.iam.IamClient; +import software.amazon.awssdk.services.sts.model.AssumeRoleRequest; +import software.amazon.awssdk.services.sts.model.AssumeRoleResponse; + +import static com.yahoo.athenz.common.server.util.config.ConfigManagerSingleton.CONFIG_MANAGER; +import static com.yahoo.athenz.instance.provider.InstanceProvider.ZTS_INSTANCE_AWS_ACCOUNT; +import static com.yahoo.athenz.instance.provider.impl.InstanceAWSProvider.*; + +public class DefaultAWSElasticKubernetesServiceValidator extends CommonKubernetesDistributionValidator { + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private static final DefaultAWSElasticKubernetesServiceValidator INSTANCE = new DefaultAWSElasticKubernetesServiceValidator(); + static final String AWS_EKS_OIDC_ISSUER_REGEX = "oidc\\.eks\\.[a-z0-9-]+\\.amazonaws\\.com"; + private static final Pattern AWS_EKS_OIDC_ISSUER_PATTERN = Pattern.compile(AWS_EKS_OIDC_ISSUER_REGEX); + + private static final String ZTS_PROP_K8S_PROVIDER_ATTESTATION_AWS_ASSUME_ROLE_NAME = "athenz.zts.k8s_provider_attestation_aws_assume_role_name"; + private static final String ASSUME_ROLE_NAME = System.getProperty(ZTS_PROP_K8S_PROVIDER_ATTESTATION_AWS_ASSUME_ROLE_NAME, "oidc-issuers-reader"); + static final String ZTS_PROP_K8S_PROVIDER_AWS_ATTR_VALIDATOR_FACTORY_CLASS = "athenz.zts.k8s_provider_aws_attr_validator_factory_class"; + + StsClient stsClient; + String serverRegion; + + Set awsDNSSuffixes = new HashSet<>(); + List eksDnsSuffixes; + DynamicConfigCsv eksClusterNames; // list of eks cluster names + + private static final String ZTS_PROP_K8S_PROVIDER_AWS_ATTESTATION_USING_IAM_ROLE = "athenz.zts.k8s_provider_aws_attestation_using_iam_role"; + DynamicConfigBoolean useIamRoleForIssuerAttestation; + AttrValidator attrValidator; + + public static DefaultAWSElasticKubernetesServiceValidator getInstance() { + return INSTANCE; + } + + private DefaultAWSElasticKubernetesServiceValidator() { + } + + static AttrValidator newAttrValidator(final SSLContext sslContext) { + final String factoryClass = System.getProperty(ZTS_PROP_K8S_PROVIDER_AWS_ATTR_VALIDATOR_FACTORY_CLASS); + LOGGER.info("AWS K8S AttributeValidatorFactory class: {}", factoryClass); + if (factoryClass == null) { + return null; + } + + AttrValidatorFactory attrValidatorFactory; + try { + attrValidatorFactory = (AttrValidatorFactory) Class.forName(factoryClass).getConstructor().newInstance(); + } catch (Exception e) { + LOGGER.error("Invalid AttributeValidatorFactory class: {}", factoryClass, e); + throw new IllegalArgumentException("Invalid AttributeValidatorFactory class"); + } + + return attrValidatorFactory.create(sslContext); + } + + @Override + public void initialize(final SSLContext sslContext, Authorizer authorizer) { + super.initialize(sslContext, authorizer); + serverRegion = System.getProperty(AWS_PROP_REGION_NAME); + + useIamRoleForIssuerAttestation = new DynamicConfigBoolean(CONFIG_MANAGER, ZTS_PROP_K8S_PROVIDER_AWS_ATTESTATION_USING_IAM_ROLE, true); + + if (useIamRoleForIssuerValidation()) { + // Create an STS client using default credentials + stsClient = StsClient.builder().credentialsProvider(DefaultCredentialsProvider.builder().build()) + .region(Region.of(serverRegion)).build(); + } + final String dnsSuffix = System.getProperty(AWS_PROP_DNS_SUFFIX); + if (!StringUtil.isEmpty(dnsSuffix)) { + awsDNSSuffixes.addAll(Arrays.asList(dnsSuffix.split(","))); + } + // get our allowed eks dns suffixes + eksDnsSuffixes = InstanceUtils.processK8SDnsSuffixList(AWS_PROP_EKS_DNS_SUFFIX); + // get our dynamic list of eks cluster names + eksClusterNames = new DynamicConfigCsv(CONFIG_MANAGER, AWS_PROP_EKS_CLUSTER_NAMES, null); + + this.attrValidator = newAttrValidator(sslContext); + } + + @Override + public String validateIssuer(InstanceConfirmation confirmation, IdTokenAttestationData attestationData, StringBuilder errMsg) { + + String issuer = getIssuerFromToken(attestationData, errMsg); + if (StringUtil.isEmpty(issuer)) { + return null; + } + + String issuerDomain = InstanceUtils.extractURLDomainName(issuer); + if (issuerDomain == null) { + return null; + } + Matcher matcher = AWS_EKS_OIDC_ISSUER_PATTERN.matcher(issuerDomain); + if (!matcher.matches()) { + return null; + } + + if (useIamRoleForIssuerValidation()) { + String awsAccount = confirmation.getAttributes().get(ZTS_INSTANCE_AWS_ACCOUNT); + if (!verifyIssuerPresenceInDomainAWSAccount(issuer, awsAccount)) { + return null; + } + // If the issuer is present in the same AWS account as the requested identity + // then we should use the same for the launch authorization + confirmation.getAttributes().put(ZTS_INSTANCE_ISSUER_AWS_ACCOUNT, awsAccount); + } else { + if (attrValidator != null) { + confirmation.getAttributes().put(ZTS_INSTANCE_UNATTESTED_ISSUER, issuer); + // Confirm the issuer as per the attribute validator + if (!attrValidator.confirm(confirmation)) { + return null; + } + } + } + + final String domainName = confirmation.getDomain(); + final String serviceName = confirmation.getService(); + // attribute set after iam role validation or attribute validation + final String issuerAwsAccount = confirmation.getAttributes().get(ZTS_INSTANCE_ISSUER_AWS_ACCOUNT); + final String resource = String.format("%s:%s:%s", domainName, serviceName, issuerAwsAccount); + + Principal principal = SimplePrincipal.create(domainName, serviceName, (String) null); + boolean accessCheck = authorizer.access(ACTION_LAUNCH, resource, principal, null); + if (!accessCheck) { + errMsg.append("eks launch authorization check failed for action: ").append(ACTION_LAUNCH) + .append(" resource: ").append(resource); + return null; + } + + return issuer; + } + + IamClient getIamClient(final String awsAccount) { + + final String roleArn = String.format("arn:aws:iam::%s:role/%s", awsAccount, ASSUME_ROLE_NAME); + final String roleSessionName = ASSUME_ROLE_NAME + "-Session"; + + // Assume the role in the target AWS account + + AssumeRoleRequest assumeRoleRequest = AssumeRoleRequest.builder() + .roleArn(roleArn).roleSessionName(roleSessionName).build(); + AssumeRoleResponse assumeRoleResponse = stsClient.assumeRole(assumeRoleRequest); + + // Create Static Credentials Provider + + StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create( + AwsSessionCredentials.create(assumeRoleResponse.credentials().accessKeyId(), + assumeRoleResponse.credentials().secretAccessKey(), + assumeRoleResponse.credentials().sessionToken())); + + // Create IAM Client + + return IamClient.builder().credentialsProvider(credentialsProvider).region(Region.of(serverRegion)).build(); + } + + boolean verifyIssuerPresenceInDomainAWSAccount(final String issuer, final String awsAccount) { + + boolean result = false; + + // get our IAM Client + + IamClient iamClient = getIamClient(awsAccount); + + // Call the IAM API to get the list of OIDC issuers + + ListOpenIdConnectProvidersRequest request = ListOpenIdConnectProvidersRequest.builder().build(); + ListOpenIdConnectProvidersResponse response = iamClient.listOpenIDConnectProviders(request); + List oidcIssuers = response.openIDConnectProviderList(); + if (oidcIssuers != null) { + String issuerWithoutProtocol = issuer.replaceFirst("^https://", ""); + for (OpenIDConnectProviderListEntry oidcIssuer : oidcIssuers) { + if (oidcIssuer != null && oidcIssuer.arn() != null && oidcIssuer.arn().endsWith(issuerWithoutProtocol)) { + result = true; + break; + } + } + } + return result; + } + + @Override + public boolean validateSanDNSEntries(InstanceConfirmation confirmation, StringBuilder errMsg) { + + StringBuilder instanceId = new StringBuilder(256); + final Map instanceAttributes = confirmation.getAttributes(); + final String awsAccount = InstanceUtils.getInstanceProperty(instanceAttributes, ZTS_INSTANCE_AWS_ACCOUNT); + if (StringUtil.isEmpty(awsAccount)) { + errMsg.append("Unable to find AWS account number"); + return false; + } + if (!InstanceUtils.validateCertRequestSanDnsNames(instanceAttributes, confirmation.getDomain(), + confirmation.getService(), awsDNSSuffixes, eksDnsSuffixes, eksClusterNames.getStringsList(), + true, instanceId, null)) { + errMsg.append("Unable to validate certificate request hostnames"); + return false; + } + return true; + } + + boolean useIamRoleForIssuerValidation() { + return Boolean.TRUE.equals(useIamRoleForIssuerAttestation.get()); + } +} \ No newline at end of file diff --git a/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultGCPGoogleKubernetesEngineValidator.java b/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultGCPGoogleKubernetesEngineValidator.java new file mode 100644 index 0000000..2b632ee --- /dev/null +++ b/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultGCPGoogleKubernetesEngineValidator.java @@ -0,0 +1,129 @@ +package com.yahoo.athenz.instance.provider.impl; + +import com.yahoo.athenz.auth.Authorizer; +import com.yahoo.athenz.auth.Principal; +import com.yahoo.athenz.auth.impl.SimplePrincipal; +import com.yahoo.athenz.common.server.util.config.dynamic.DynamicConfigCsv; +import com.yahoo.athenz.instance.provider.AttrValidator; +import com.yahoo.athenz.instance.provider.AttrValidatorFactory; +import com.yahoo.athenz.instance.provider.InstanceConfirmation; +import com.yahoo.athenz.instance.provider.InstanceProvider; +import javax.net.ssl.SSLContext; +import org.eclipse.jetty.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.invoke.MethodHandles; +import java.util.*; + +import static com.yahoo.athenz.common.server.util.config.ConfigManagerSingleton.CONFIG_MANAGER; +import static com.yahoo.athenz.instance.provider.impl.InstanceGCPProvider.*; + +public class DefaultGCPGoogleKubernetesEngineValidator extends CommonKubernetesDistributionValidator { + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + Set gcpDNSSuffixes = new HashSet<>(); + List gkeDnsSuffixes; + DynamicConfigCsv gkeClusterNames; + + private static final DefaultGCPGoogleKubernetesEngineValidator INSTANCE = new DefaultGCPGoogleKubernetesEngineValidator(); + static final String GCP_OIDC_ISSUER_PREFIX = "https://container.googleapis.com/v1/projects/"; + AttrValidator attrValidator; + static final String ZTS_PROP_K8S_PROVIDER_GCP_ATTR_VALIDATOR_FACTORY_CLASS = "athenz.zts.k8s_provider_gcp_attr_validator_factory_class"; + + public static DefaultGCPGoogleKubernetesEngineValidator getInstance() { + return INSTANCE; + } + private DefaultGCPGoogleKubernetesEngineValidator() { + } + + static AttrValidator newAttrValidator(final SSLContext sslContext) { + final String factoryClass = System.getProperty(ZTS_PROP_K8S_PROVIDER_GCP_ATTR_VALIDATOR_FACTORY_CLASS); + LOGGER.info("GCP K8S AttributeValidatorFactory class: {}", factoryClass); + if (factoryClass == null) { + return null; + } + + AttrValidatorFactory attrValidatorFactory; + try { + attrValidatorFactory = (AttrValidatorFactory) Class.forName(factoryClass).getConstructor().newInstance(); + } catch (Exception e) { + LOGGER.error("Invalid AttributeValidatorFactory class: {}", factoryClass, e); + throw new IllegalArgumentException("Invalid AttributeValidatorFactory class"); + } + + return attrValidatorFactory.create(sslContext); + } + + @Override + public void initialize(final SSLContext sslContext, Authorizer authorizer) { + super.initialize(sslContext, authorizer); + final String dnsSuffix = System.getProperty(GCP_PROP_DNS_SUFFIX); + if (!StringUtil.isEmpty(dnsSuffix)) { + gcpDNSSuffixes.addAll(Arrays.asList(dnsSuffix.split(","))); + } + // get our allowed gke dns suffixes + gkeDnsSuffixes = InstanceUtils.processK8SDnsSuffixList(GCP_PROP_GKE_DNS_SUFFIX); + // get our dynamic list of gke cluster names + gkeClusterNames = new DynamicConfigCsv(CONFIG_MANAGER, GCP_PROP_GKE_CLUSTER_NAMES, null); + this.attrValidator = newAttrValidator(sslContext); + } + + @Override + public String validateIssuer(InstanceConfirmation confirmation, IdTokenAttestationData attestationData, StringBuilder errMsg) { + String issuer = getIssuerFromToken(attestationData, errMsg); + if (StringUtil.isEmpty(issuer)) { + return null; + } + String gcpProject = confirmation.getAttributes().get(InstanceProvider.ZTS_INSTANCE_GCP_PROJECT); + if (!issuer.startsWith(GCP_OIDC_ISSUER_PREFIX + gcpProject)) { + // could be a multi-tenant setup where the issuer is not present in the identity's GCP project + if (attrValidator != null) { + confirmation.getAttributes().put(ZTS_INSTANCE_UNATTESTED_ISSUER, issuer); + // Confirm the issuer as per the attribute validator + if (!attrValidator.confirm(confirmation)) { + return null; + } + } else { + errMsg.append("Issuer is not present in the GCP project associated with the domain"); + return null; + } + } else { + // issuer exists in the same GCP project as the requested identity + confirmation.getAttributes().put(ZTS_INSTANCE_ISSUER_GCP_PROJECT, gcpProject); + } + + final String domainName = confirmation.getDomain(); + final String serviceName = confirmation.getService(); + // attribute set after verification above or attribute validation + final String issuerGcpProject = confirmation.getAttributes().get(ZTS_INSTANCE_ISSUER_GCP_PROJECT); + final String resource = String.format("%s:%s:%s", domainName, serviceName, issuerGcpProject); + + Principal principal = SimplePrincipal.create(domainName, serviceName, (String) null); + boolean accessCheck = authorizer.access(ACTION_LAUNCH, resource, principal, null); + if (!accessCheck) { + errMsg.append("gke launch authorization check failed for action: ").append(ACTION_LAUNCH) + .append(" resource: ").append(resource); + return null; + } + return issuer; + } + + @Override + public boolean validateSanDNSEntries(InstanceConfirmation confirmation, StringBuilder errMsg) { + StringBuilder instanceId = new StringBuilder(256); + final Map instanceAttributes = confirmation.getAttributes(); + final String gcpProject = InstanceUtils.getInstanceProperty(instanceAttributes, ZTS_INSTANCE_GCP_PROJECT); + if (StringUtil.isEmpty(gcpProject)) { + errMsg.append("Unable to find GCP project id"); + return false; + } + if (!InstanceUtils.validateCertRequestSanDnsNames(instanceAttributes, confirmation.getDomain(), + confirmation.getService(), gcpDNSSuffixes, gkeDnsSuffixes, gkeClusterNames.getStringsList(), + true, instanceId, null)) { + errMsg.append("Unable to validate certificate request hostnames"); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultKubernetesValidator.java b/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultKubernetesValidator.java new file mode 100644 index 0000000..254ac55 --- /dev/null +++ b/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultKubernetesValidator.java @@ -0,0 +1,90 @@ +package com.yahoo.athenz.instance.provider.impl; + +import com.yahoo.athenz.auth.Authorizer; +import com.yahoo.athenz.auth.Principal; +import com.yahoo.athenz.auth.impl.SimplePrincipal; +import com.yahoo.athenz.instance.provider.InstanceConfirmation; +import javax.net.ssl.SSLContext; +import org.eclipse.jetty.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.invoke.MethodHandles; +import java.util.*; + +import static com.yahoo.athenz.instance.provider.impl.InstanceGCPProvider.*; + +public class DefaultKubernetesValidator extends CommonKubernetesDistributionValidator { + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + Set k8sDNSSuffixes; + + private static final DefaultKubernetesValidator INSTANCE = new DefaultKubernetesValidator(); + static final String K8S_OIDC_ISSUER = "https://kubernetes.default.svc.cluster.local"; + static final String K8S_PROP_BOOT_TIME_OFFSET = "athenz.zts.k8s_boot_time_offset"; + static final String K8S_PROP_DNS_SUFFIX = "athenz.zts.k8s_dns_suffix"; + + public static DefaultKubernetesValidator getInstance() { + return INSTANCE; + } + private DefaultKubernetesValidator() { + } + + @Override + public void initialize(final SSLContext sslContext, Authorizer authorizer) { + super.initialize(sslContext, authorizer); + final String dnsSuffix = System.getProperty(K8S_PROP_DNS_SUFFIX); + if (!StringUtil.isEmpty(dnsSuffix)) { + k8sDNSSuffixes.addAll(Arrays.asList(dnsSuffix.split(","))); + } + } + + @Override + public String validateIssuer(InstanceConfirmation confirmation, IdTokenAttestationData attestationData, StringBuilder errMsg) { + String issuer = getIssuerFromToken(attestationData, errMsg); + if (StringUtil.isEmpty(issuer)) { + errMsg.append("Issuer is empty"); + return null; + } + if (!issuer.equals(K8S_OIDC_ISSUER)) { + errMsg.append("Issuer is not ").append(K8S_OIDC_ISSUER); + return null; + } + final Map instanceAttributes = confirmation.getAttributes(); + final String cloudName = InstanceUtils.getInstanceProperty(instanceAttributes, ZTS_INSTANCE_CLOUD); + final String providerName = confirmation.getProvider(); + final String k8sNamespaceName = attestationData.getIdentityToken(); + final String k8sServiceAccountName = attestationData.getIdentityToken(); + + final String domainName = confirmation.getDomain(); + final String serviceName = confirmation.getService(); + // attribute set after verification above or attribute validation + final String resource = String.format("cloud:%s:provider:%s:system:serviceaccount:%s:%s", cloudName, providerName, k8sNamespaceName, k8sServiceAccountName); + + Principal principal = SimplePrincipal.create(domainName, serviceName, (String) null); + boolean accessCheck = authorizer.access(ACTION_LAUNCH, resource, principal, null); + if (!accessCheck) { + errMsg.append("k8s launch authorization check failed for action: ").append(ACTION_LAUNCH) + .append(" resource: ").append(resource); + return null; + } + return issuer; + } + + @Override + public boolean validateSanDNSEntries(InstanceConfirmation confirmation, StringBuilder errMsg) { + StringBuilder instanceId = new StringBuilder(256); + final Map instanceAttributes = confirmation.getAttributes(); + final String cloudName = InstanceUtils.getInstanceProperty(instanceAttributes, ZTS_INSTANCE_CLOUD); + if (StringUtil.isEmpty(cloudName) || cloudName.equals("")) { + errMsg.append("Unable to find cloud name"); + return false; + } + if (!InstanceUtils.validateCertRequestSanDnsNames(instanceAttributes, confirmation.getDomain(), + confirmation.getService(), k8sDNSSuffixes, null, null, false, instanceId, null)) { + errMsg.append("Unable to validate certificate request hostnames for SAN DNS names"); + return false; + } + return true; + } +} diff --git a/src/main/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProvider.java b/src/main/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProvider.java index 21521bb..eed595a 100644 --- a/src/main/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProvider.java +++ b/src/main/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProvider.java @@ -305,16 +305,15 @@ boolean validateTenantDomainToken(final JWTClaimsSet claimsSet, final String dom // we need to extract and generate our action value for the authz check - final String action = "jenkins-pipeline"; + final String action = "run_jenkins_pipeline"; // we need to generate our resource value based on the subject - final String subject = claimsSet.getSubject(); + final String resource = claimsSet.getSubject(); // generate our principal object and carry out authorization check - - final String resource = domainName + ":" + subject; Principal principal = SimplePrincipal.create(domainName, serviceName, (String) null); + boolean accessCheck = authorizer.access(action, resource, principal, null); if (!accessCheck) { errMsg.append("authorization check failed for action: ").append(action) diff --git a/src/main/java/com/yahoo/athenz/instance/provider/impl/SimpleKubernetesDistributionValidatorFactory.java b/src/main/java/com/yahoo/athenz/instance/provider/impl/SimpleKubernetesDistributionValidatorFactory.java new file mode 100644 index 0000000..70abfdc --- /dev/null +++ b/src/main/java/com/yahoo/athenz/instance/provider/impl/SimpleKubernetesDistributionValidatorFactory.java @@ -0,0 +1,23 @@ +package com.yahoo.athenz.instance.provider.impl; + +import com.yahoo.athenz.instance.provider.KubernetesDistributionValidator; +import com.yahoo.athenz.instance.provider.KubernetesDistributionValidatorFactory; + +import java.util.HashMap; +import java.util.Map; + +public class SimpleKubernetesDistributionValidatorFactory implements KubernetesDistributionValidatorFactory { + + Map supportedDistributionsMap = new HashMap<>(); + static final String CLOUD_K8S = "k8s"; + + @Override + public void initialize() { + supportedDistributionsMap.put(CLOUD_K8S, DefaultKubernetesValidator.getInstance()); + } + + @Override + public Map getSupportedDistributions() { + return supportedDistributionsMap; + } +} \ No newline at end of file diff --git a/src/test/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProviderTest.java b/src/test/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProviderTest.java index 052c856..a7efae1 100644 --- a/src/test/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProviderTest.java +++ b/src/test/java/com/yahoo/athenz/instance/provider/impl/InstanceJenkinsProviderTest.java @@ -119,7 +119,7 @@ public void testConfirmInstance() throws JOSEException, ProviderResourceExceptio Authorizer authorizer = Mockito.mock(Authorizer.class); Principal principal = SimplePrincipal.create("sports", "api", (String) null); - Mockito.when(authorizer.access("jenkins-pipeline", "sports:https://jenkins.athenz.svc.cluster.local/job/test-project/1", principal, null)) + Mockito.when(authorizer.access("run_jenkins_pipeline", "https://jenkins.athenz.svc.cluster.local/job/test-project/1", principal, null)) .thenReturn(true); provider.setAuthorizer(authorizer); @@ -156,7 +156,7 @@ public void testConfirmInstanceFailuresInvalidSANEntries() throws JOSEException Authorizer authorizer = Mockito.mock(Authorizer.class); Principal principal = SimplePrincipal.create("sports", "api", (String) null); - Mockito.when(authorizer.access("jenkins-pipeline", "sports:https://jenkins.athenz.svc.cluster.local/job/test-project/1", principal, null)) + Mockito.when(authorizer.access("run_jenkins_pipeline", "https://jenkins.athenz.svc.cluster.local/job/test-project/1", principal, null)) .thenReturn(true); provider.setAuthorizer(authorizer);