From 38b9513d25fa4fa6f77695d86b47180754d934fc Mon Sep 17 00:00:00 2001 From: Abhijeet V <31417623+abvaidya@users.noreply.github.com> Date: Wed, 15 May 2024 09:02:46 -0700 Subject: [PATCH] use issuer aws account or gcp project for launch authorization Signed-off-by: Abhijeet V <31417623+abvaidya@users.noreply.github.com> --- .../athenz/instance/provider/InstanceProvider.java | 2 ++ .../DefaultAWSElasticKubernetesServiceValidator.java | 12 ++++++++---- .../DefaultGCPGoogleKubernetesEngineValidator.java | 7 ++++++- servers/zts/conf/zts.properties | 11 +++++++++++ .../yahoo/athenz/zts/InstanceProviderManager.java | 3 ++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/InstanceProvider.java b/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/InstanceProvider.java index 89f5fe90a66..d0f166f92b0 100644 --- a/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/InstanceProvider.java +++ b/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/InstanceProvider.java @@ -72,6 +72,8 @@ public interface InstanceProvider { String ZTS_INSTANCE_CERT_ISSUER_DN = "certIssuerDn"; String ZTS_INSTANCE_CLOUD = "instanceCloud"; String ZTS_INSTANCE_UNATTESTED_ISSUER = "unattestedIssuer"; + String ZTS_INSTANCE_ISSUER_AWS_ACCOUNT = "issuerAwsAccount"; + String ZTS_INSTANCE_ISSUER_GCP_PROJECT = "issuerGcpProject"; /** * Host cert specific attribute names */ diff --git a/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultAWSElasticKubernetesServiceValidator.java b/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultAWSElasticKubernetesServiceValidator.java index af27df2342e..91f24fcad7b 100644 --- a/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultAWSElasticKubernetesServiceValidator.java +++ b/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultAWSElasticKubernetesServiceValidator.java @@ -139,10 +139,13 @@ public String validateIssuer(InstanceConfirmation confirmation, IdTokenAttestati } if (useIamRoleForIssuerValidation()) { - if (!verifyIssuerPresenceInDomainAWSAccount(issuer, - confirmation.getAttributes().get(ZTS_INSTANCE_AWS_ACCOUNT))) { + 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); @@ -155,8 +158,9 @@ public String validateIssuer(InstanceConfirmation confirmation, IdTokenAttestati final String domainName = confirmation.getDomain(); final String serviceName = confirmation.getService(); - final String resource = String.format("%s:%s:%s", domainName, serviceName, - confirmation.getAttributes().get(ZTS_INSTANCE_AWS_ACCOUNT)); + // 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); diff --git a/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultGCPGoogleKubernetesEngineValidator.java b/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultGCPGoogleKubernetesEngineValidator.java index 74dcd4fca86..4cca82402fe 100644 --- a/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultGCPGoogleKubernetesEngineValidator.java +++ b/libs/java/instance_provider/src/main/java/com/yahoo/athenz/instance/provider/impl/DefaultGCPGoogleKubernetesEngineValidator.java @@ -103,11 +103,16 @@ public String validateIssuer(InstanceConfirmation confirmation, IdTokenAttestati 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(); - final String resource = String.format("%s:%s:%s", domainName, serviceName, gcpProject); + // 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); diff --git a/servers/zts/conf/zts.properties b/servers/zts/conf/zts.properties index 7ae71ebe5dd..5069fc8d285 100644 --- a/servers/zts/conf/zts.properties +++ b/servers/zts/conf/zts.properties @@ -742,3 +742,14 @@ athenz.zts.k8s_provider_distribution_validator_factory_class=com.yahoo.athenz.in # the host's private IP address (as specified by the provider) and # the client IP address from the connection request object. #athenz.zts.ssh_cert_validate_ip=false + +# This property configures the InstanceK8SProvider to use AWS IAM to authorize the OIDC issuer +# issuing id_token which is used by the provider as attestation data +#athenz.zts.k8s_provider_aws_attestation_using_iam_role=true + +# If AWS IAM is configured to authorize the OIDC issuer then this property specifies the IAM role name +#athenz.zts.k8s_provider_attestation_aws_assume_role_name=oidc-issuers-reader + +# This property configures the factory providing internal implementation of the AttributeValidator interface +# as a plugin to validate the identity attributes in the request +# athenz.zts.k8s_provider_aws_attr_validator_factory_class= diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/InstanceProviderManager.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/InstanceProviderManager.java index e2f85fc656b..39c11f2136e 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/InstanceProviderManager.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/InstanceProviderManager.java @@ -171,7 +171,6 @@ InstanceProvider getClassProvider(String className, String providerName, SSLCont LOGGER.error("Unable to get new instance for provider {}", className, ex); return null; } - provider.initialize(providerName, className, context, keyStore); provider.setHostnameResolver(hostnameResolver); provider.setRolesProvider(dataStore); provider.setExternalCredentialsProvider(new InstanceExternalCredentialsProvider(providerName, ztsHandler)); @@ -180,6 +179,8 @@ InstanceProvider getClassProvider(String className, String providerName, SSLCont if (ZTS_PROVIDER.equals(providerName)) { provider.setPrivateKey(serverPrivateKey.getKey(), serverPrivateKey.getId(), serverPrivateKey.getAlgorithm()); } + // initialize provider after setting all the fields so that the initialize code can use them + provider.initialize(providerName, className, context, keyStore); providerMap.put(classKey, provider); return provider;