mirror of
https://github.com/openshift/openshift-docs.git
synced 2026-02-05 12:46:18 +01:00
Add token auth via CCO for Operator authors (AWS STS)
This commit is contained in:
committed by
openshift-cherrypick-robot
parent
af53b3f679
commit
d613745ba6
@@ -1826,6 +1826,8 @@ Topics:
|
||||
File: osdk-working-bundle-images
|
||||
- Name: Complying with pod security admission
|
||||
File: osdk-complying-with-psa
|
||||
- Name: Token authentication for Operators on cloud providers
|
||||
File: osdk-token-auth
|
||||
- Name: Validating Operators using the scorecard
|
||||
File: osdk-scorecard
|
||||
- Name: Validating Operator bundles
|
||||
|
||||
@@ -53,11 +53,9 @@ include::modules/cco-short-term-creds-component-permissions-aws.adoc[leveloffset
|
||||
//OLM-managed Operator support for authentication with AWS STS
|
||||
include::modules/cco-short-term-creds-aws-olm.adoc[leveloffset=+2]
|
||||
|
||||
////
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
* xr\ef:../../operators/operator_sdk/osdk-token-auth.html#osdk-aws-sts_osdk-token-auth[CCO-based workflow for OLM-managed Operators with AWS STS]
|
||||
////
|
||||
* xref:../../operators/operator_sdk/osdk-token-auth.adoc#osdk-cco-aws-sts_osdk-token-auth[CCO-based workflow for OLM-managed Operators with AWS STS]
|
||||
|
||||
[id="cco-short-term-creds-gcp_{context}"]
|
||||
== GCP Workload Identity
|
||||
|
||||
@@ -153,11 +153,27 @@ spec:
|
||||
<6> The `env` parameter defines a list of Environment Variables that must exist in all containers in the pod created by OLM.
|
||||
<7> The `envFrom` parameter defines a list of sources to populate Environment Variables in the container.
|
||||
<8> The `volumes` parameter defines a list of Volumes that must exist on the pod created by OLM.
|
||||
<9> The `volumeMounts` parameter defines a list of VolumeMounts that must exist in all containers in the pod created by OLM. If a `volumeMount` references a `volume` that does not exist, OLM fails to deploy the Operator.
|
||||
<9> The `volumeMounts` parameter defines a list of volume mounts that must exist in all containers in the pod created by OLM. If a `volumeMount` references a `volume` that does not exist, OLM fails to deploy the Operator.
|
||||
<10> The `tolerations` parameter defines a list of Tolerations for the pod created by OLM.
|
||||
<11> The `resources` parameter defines resource constraints for all the containers in the pod created by OLM.
|
||||
<12> The `nodeSelector` parameter defines a `NodeSelector` for the pod created by OLM.
|
||||
|
||||
. If the cluster is in STS mode, include the following fields in the `Subscription` object:
|
||||
+
|
||||
[source,yaml]
|
||||
----
|
||||
kind: Subscription
|
||||
# ...
|
||||
spec:
|
||||
installPlanApproval: Manual <1>
|
||||
config:
|
||||
env:
|
||||
- name: ROLEARN
|
||||
value: "<role_arn>" <2>
|
||||
----
|
||||
<1> Subscriptions with automatic update approvals are not recommended because there might be permission changes to make prior to updating. Subscriptions with manual update approvals ensure that administrators have the opportunity to verify the permissions of the later version and take any necessary steps prior to update.
|
||||
<2> Include the role ARN details.
|
||||
|
||||
. Create the `Subscription` object:
|
||||
+
|
||||
[source,terminal]
|
||||
|
||||
@@ -78,9 +78,18 @@ ifdef::olm-user[]
|
||||
.. Choose a specific, single namespace in which to install the Operator. The Operator will only watch and be made available for use in this single namespace.
|
||||
endif::[]
|
||||
|
||||
.. Select an *Update channel* (if more than one is available).
|
||||
.. If the cluster is in STS mode, add the role ARN in the *role ARN* field.
|
||||
|
||||
.. If more than one update channel is available, select an *Update channel*.
|
||||
|
||||
.. Select *Automatic* or *Manual* approval strategy, as described earlier.
|
||||
+
|
||||
[IMPORTANT]
|
||||
====
|
||||
If the web console shows that the cluster is in "STS mode", you must set *Update approval* to *Manual*.
|
||||
|
||||
Subscriptions with automatic update approvals are not recommended because there might be permission changes to make prior to updating. Subscriptions with manual update approvals ensure that administrators have the opportunity to verify the permissions of the later version and take any necessary steps prior to update.
|
||||
====
|
||||
|
||||
. Click *Install* to make the Operator available to the selected namespaces on this {product-title} cluster.
|
||||
|
||||
|
||||
26
modules/osdk-cco-aws-sts-alt.adoc
Normal file
26
modules/osdk-cco-aws-sts-alt.adoc
Normal file
@@ -0,0 +1,26 @@
|
||||
// Module included in the following assemblies:
|
||||
//
|
||||
// * operators/operator_sdk/osdk-token-auth.adoc
|
||||
|
||||
:_content-type: CONCEPT
|
||||
[id="osdk-cco-aws-sts-alt_{context}"]
|
||||
= Alternative method
|
||||
|
||||
As an alternative method for Operator authors, you can indicate that the user is responsible for creating the `CredentialsRequest` object for the Cloud Credential Operator (CCO) before installing the Operator.
|
||||
|
||||
The Operator instructions must indicate the following to users:
|
||||
|
||||
* Provide a YAML version of a `CredentialsRequest` object, either by providing the YAML inline in the instructions or pointing users to a download location
|
||||
* Instruct the user to create the `CredentialsRequest` object
|
||||
|
||||
In {product-title} 4.14 and later, after the `CredentialsRequest` object appears on the cluster with the appropriate STS information added, the Operator can then read the CCO-generated `Secret` or mount it, having defined the mount in the cluster service version (CSV).
|
||||
|
||||
For earlier versions of {product-title}, the Operator instructions must also indicate the following to users:
|
||||
|
||||
* Use the CCO utility (`ccoctl`) to generate the `Secret` YAML object from the `CredentialsRequest` object
|
||||
* Apply the `Secret` object to the cluster in the appropriate namespace
|
||||
|
||||
The Operator still must be able to consume the resulting secret to communicate with cloud APIs. Because in this case the secret is created by the user before the Operator is installed, the Operator can do either of the following:
|
||||
|
||||
* Define an explicit mount in the `Deployment` object within the CSV
|
||||
* Programmatically read the `Secret` object from the API server, as shown in the recommended "Enabling Operators to support CCO-based workflows with AWS STS" method
|
||||
321
modules/osdk-cco-aws-sts-enabling.adoc
Normal file
321
modules/osdk-cco-aws-sts-enabling.adoc
Normal file
@@ -0,0 +1,321 @@
|
||||
// Module included in the following assemblies:
|
||||
//
|
||||
// * operators/operator_sdk/osdk-token-auth.adoc
|
||||
|
||||
:_content-type: PROCEDURE
|
||||
[id="osdk-cco-aws-sts-enabling_{context}"]
|
||||
= Enabling Operators to support CCO-based workflows with AWS STS
|
||||
|
||||
As an Operator author designing your project to run on Operator Lifecycle Manager (OLM), you can enable your Operator to authenticate against AWS on STS-enabled {product-title} clusters by customizing your project to support the Cloud Credential Operator (CCO).
|
||||
|
||||
With this method, the Operator is responsible for creating the `CredentialsRequest` object, which means the Operator requires RBAC permission to create these objects. Then, the Operator must be able to read the resulting `Secret` object.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
By default, pods related to the Operator deployment mount a `serviceAccountToken` volume so that the service account token can be referenced in the resulting `Secret` object.
|
||||
====
|
||||
|
||||
.Prerequisities
|
||||
|
||||
* {product-title} 4.14 or later
|
||||
* Cluster in STS mode
|
||||
* OLM-based Operator project
|
||||
|
||||
.Procedure
|
||||
|
||||
. Update your Operator project's `ClusterServiceVersion` (CSV) object:
|
||||
|
||||
.. Ensure your Operator has RBAC permission to create `CredentialsRequests` objects:
|
||||
+
|
||||
.Example `clusterPermissions` list
|
||||
[%collapsible]
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
# ...
|
||||
install:
|
||||
spec:
|
||||
clusterPermissions:
|
||||
- rules:
|
||||
- apiGroups:
|
||||
- "cloudcredential.openshift.io"
|
||||
resources:
|
||||
- credentialsrequests
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
----
|
||||
====
|
||||
|
||||
.. Add the following annotation to claim support for this method of CCO-based workflow with AWS STS:
|
||||
+
|
||||
[source,yaml]
|
||||
----
|
||||
# ...
|
||||
metadata:
|
||||
annotations:
|
||||
features.operators.openshift.io/token-auth-aws: "true"
|
||||
----
|
||||
|
||||
. Update your Operator project code:
|
||||
|
||||
.. Get the role ARN from the environment variable set on the pod by the `Subscription` object. For example:
|
||||
+
|
||||
[source,go]
|
||||
----
|
||||
// Get ENV var
|
||||
roleARN := os.Getenv("ROLEARN")
|
||||
setupLog.Info("getting role ARN", "role ARN = ", roleARN)
|
||||
webIdentityTokenPath := "/var/run/secrets/openshift/serviceaccount/token"
|
||||
----
|
||||
|
||||
.. Ensure you have a `CredentialsRequest` object ready to be patched and applied. For example:
|
||||
+
|
||||
.Example `CredentialsRequest` object creation
|
||||
[%collapsible]
|
||||
====
|
||||
[source,go]
|
||||
----
|
||||
import (
|
||||
minterv1 "github.com/openshift/cloud-credential-operator/pkg/apis/cloudcredential/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var in = minterv1.AWSProviderSpec{
|
||||
StatementEntries: []minterv1.StatementEntry{
|
||||
{
|
||||
Action: []string{
|
||||
"s3:*",
|
||||
},
|
||||
Effect: "Allow",
|
||||
Resource: "arn:aws:s3:*:*:*",
|
||||
},
|
||||
},
|
||||
STSIAMRoleARN: "<role_arn>",
|
||||
}
|
||||
|
||||
var codec = minterv1.Codec
|
||||
var ProviderSpec, _ = codec.EncodeProviderSpec(in.DeepCopyObject())
|
||||
|
||||
const (
|
||||
name = "<credential_request_name>"
|
||||
namespace = "<namespace_name>"
|
||||
)
|
||||
|
||||
var CredentialsRequestTemplate = &minterv1.CredentialsRequest{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: "openshift-cloud-credential-operator",
|
||||
},
|
||||
Spec: minterv1.CredentialsRequestSpec{
|
||||
ProviderSpec: ProviderSpec,
|
||||
SecretRef: corev1.ObjectReference{
|
||||
Name: "<secret_name>",
|
||||
Namespace: namespace,
|
||||
},
|
||||
ServiceAccountNames: []string{
|
||||
"<service_account_name>",
|
||||
},
|
||||
CloudTokenPath: "",
|
||||
},
|
||||
}
|
||||
----
|
||||
====
|
||||
+
|
||||
Alternatively, if you are starting from a `CredentialsRequest` object in YAML form (for example, as part of your Operator project code), you can handle it differently:
|
||||
+
|
||||
.Example `CredentialsRequest` object creation in YAML form
|
||||
[%collapsible]
|
||||
====
|
||||
[source,go]
|
||||
----
|
||||
// CredentialsRequest is a struct that represents a request for credentials
|
||||
type CredentialsRequest struct {
|
||||
APIVersion string `yaml:"apiVersion"`
|
||||
Kind string `yaml:"kind"`
|
||||
Metadata struct {
|
||||
Name string `yaml:"name"`
|
||||
Namespace string `yaml:"namespace"`
|
||||
} `yaml:"metadata"`
|
||||
Spec struct {
|
||||
SecretRef struct {
|
||||
Name string `yaml:"name"`
|
||||
Namespace string `yaml:"namespace"`
|
||||
} `yaml:"secretRef"`
|
||||
ProviderSpec struct {
|
||||
APIVersion string `yaml:"apiVersion"`
|
||||
Kind string `yaml:"kind"`
|
||||
StatementEntries []struct {
|
||||
Effect string `yaml:"effect"`
|
||||
Action []string `yaml:"action"`
|
||||
Resource string `yaml:"resource"`
|
||||
} `yaml:"statementEntries"`
|
||||
STSIAMRoleARN string `yaml:"stsIAMRoleARN"`
|
||||
} `yaml:"providerSpec"`
|
||||
|
||||
// added new field
|
||||
CloudTokenPath string `yaml:"cloudTokenPath"`
|
||||
} `yaml:"spec"`
|
||||
}
|
||||
|
||||
// ConsumeCredsRequestAddingTokenInfo is a function that takes a YAML filename and two strings as arguments
|
||||
// It unmarshals the YAML file to a CredentialsRequest object and adds the token information.
|
||||
func ConsumeCredsRequestAddingTokenInfo(fileName, tokenString, tokenPath string) (*CredentialsRequest, error) {
|
||||
// open a file containing YAML form of a CredentialsRequest
|
||||
file, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// create a new CredentialsRequest object
|
||||
cr := &CredentialsRequest{}
|
||||
|
||||
// decode the yaml file to the object
|
||||
decoder := yaml.NewDecoder(file)
|
||||
err = decoder.Decode(cr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// assign the string to the existing field in the object
|
||||
cr.Spec.CloudTokenPath = tokenPath
|
||||
|
||||
// return the modified object
|
||||
return cr, nil
|
||||
}
|
||||
----
|
||||
====
|
||||
+
|
||||
[NOTE]
|
||||
====
|
||||
Adding a `CredentialsRequest` object to the Operator bundle is not currently supported.
|
||||
====
|
||||
|
||||
.. Add the role ARN and web identity token path to the credentials request and apply it during Operator initialization:
|
||||
+
|
||||
.Example applying `CredentialsRequest` object during Operator initialization
|
||||
[%collapsible]
|
||||
====
|
||||
[source,go]
|
||||
----
|
||||
// apply credentialsRequest on install
|
||||
credReq := credreq.CredentialsRequestTemplate
|
||||
credReq.Spec.CloudTokenPath = webIdentityTokenPath
|
||||
|
||||
c := mgr.GetClient()
|
||||
if err := c.Create(context.TODO(), credReq); err != nil {
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
setupLog.Error(err, "unable to create CredRequest")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
.. Ensure your Operator can wait for a `Secret` object to show up from the CCO, as shown in the following example, which is called along with the other items you are reconciling in your Operator:
|
||||
+
|
||||
.Example wait for `Secret` object
|
||||
[%collapsible]
|
||||
====
|
||||
[source,go]
|
||||
----
|
||||
// WaitForSecret is a function that takes a Kubernetes client, a namespace, and a v1 "k8s.io/api/core/v1" name as arguments
|
||||
// It waits until the secret object with the given name exists in the given namespace
|
||||
// It returns the secret object or an error if the timeout is exceeded
|
||||
func WaitForSecret(client kubernetes.Interface, namespace, name string) (*v1.Secret, error) {
|
||||
// set a timeout of 10 minutes
|
||||
timeout := time.After(10 * time.Minute) <1>
|
||||
|
||||
// set a polling interval of 10 seconds
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
|
||||
// loop until the timeout or the secret is found
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
// timeout is exceeded, return an error
|
||||
return nil, fmt.Errorf("timed out waiting for secret %s in namespace %s", name, namespace)
|
||||
// add to this error with a pointer to instructions for following a manual path to a Secret that will work on STS
|
||||
case <-ticker.C:
|
||||
// polling interval is reached, try to get the secret
|
||||
secret, err := client.CoreV1().Secrets(namespace).Get(context.Background(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
// secret does not exist yet, continue waiting
|
||||
continue
|
||||
} else {
|
||||
// some other error occurred, return it
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// secret is found, return it
|
||||
return secret, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> The `timeout` value is based on an estimate of how fast the CCO might detect an added `CredentialsRequest` object and generate a `Secret` object. You might consider lowering the time or creating custom feedback for cluster administrators that could be wondering why the Operator is not yet accessing the cloud resources.
|
||||
====
|
||||
|
||||
.. Set up the AWS configuration by reading the secret created by the CCO from the credentials request and creating the AWS config file containing the data from that secret:
|
||||
+
|
||||
.Example AWS configuration creation
|
||||
[%collapsible]
|
||||
====
|
||||
[source,go]
|
||||
----
|
||||
func SharedCredentialsFileFromSecret(secret *corev1.Secret) (string, error) {
|
||||
var data []byte
|
||||
switch {
|
||||
case len(secret.Data["credentials"]) > 0:
|
||||
data = secret.Data["credentials"]
|
||||
default:
|
||||
return "", errors.New("invalid secret for aws credentials")
|
||||
}
|
||||
|
||||
|
||||
f, err := ioutil.TempFile("", "aws-shared-credentials")
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to create file for shared credentials")
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.Write(data); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to write credentials to %s", f.Name())
|
||||
}
|
||||
return f.Name(), nil
|
||||
}
|
||||
----
|
||||
====
|
||||
+
|
||||
[IMPORTANT]
|
||||
====
|
||||
The secret is assumed to exist, but your Operator code should wait and retry when using this secret to give time to the CCO to create the secret.
|
||||
|
||||
Additionally, the wait period should eventually time out and warn users that the {product-title} cluster version, and therefore the CCO, might be an earlier version that does not support the `CredentialsRequest` object workflow with STS detection. In such cases, instruct users that they must add a secret by using another method.
|
||||
====
|
||||
|
||||
.. Configure the AWS SDK session, for example:
|
||||
+
|
||||
.Example AWS SDK session configuration
|
||||
[%collapsible]
|
||||
====
|
||||
[source,go]
|
||||
----
|
||||
sharedCredentialsFile, err := SharedCredentialsFileFromSecret(secret)
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
options := session.Options{
|
||||
SharedConfigState: session.SharedConfigEnable,
|
||||
SharedConfigFiles: []string{sharedCredentialsFile},
|
||||
}
|
||||
----
|
||||
====
|
||||
58
modules/osdk-cco-aws-sts-role.adoc
Normal file
58
modules/osdk-cco-aws-sts-role.adoc
Normal file
@@ -0,0 +1,58 @@
|
||||
// Module included in the following assemblies:
|
||||
//
|
||||
// * operators/operator_sdk/osdk-token-auth.adoc
|
||||
|
||||
:_content-type: REFERENCE
|
||||
[id="osdk-cco-aws-sts-role_{context}"]
|
||||
= Role specification
|
||||
|
||||
The Operator description should contain the specifics of the role required to be created before installation, ideally in the form of a script that the administrator can run. For example:
|
||||
|
||||
.Example role creation script
|
||||
[%collapsible]
|
||||
====
|
||||
[source,bash]
|
||||
----
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
|
||||
OIDC_PROVIDER=$(oc get authentication cluster -ojson | jq -r .spec.serviceAccountIssuer | sed -e "s/^https:\/\///")
|
||||
NAMESPACE=my-namespace
|
||||
SERVICE_ACCOUNT_NAME="my-service-account"
|
||||
POLICY_ARN_STRINGS="arn:aws:iam::aws:policy/AmazonS3FullAccess"
|
||||
|
||||
|
||||
read -r -d '' TRUST_RELATIONSHIP <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"${OIDC_PROVIDER}:sub": "system:serviceaccount:${NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "${TRUST_RELATIONSHIP}" > trust.json
|
||||
|
||||
aws iam create-role --role-name "$SERVICE_ACCOUNT_NAME" --assume-role-policy-document file://trust.json --description "role for demo"
|
||||
|
||||
while IFS= read -r POLICY_ARN; do
|
||||
echo -n "Attaching $POLICY_ARN ... "
|
||||
aws iam attach-role-policy \
|
||||
--role-name "$SERVICE_ACCOUNT_NAME" \
|
||||
--policy-arn "${POLICY_ARN}"
|
||||
echo "ok."
|
||||
done <<< "$POLICY_ARN_STRINGS"
|
||||
----
|
||||
====
|
||||
46
modules/osdk-cco-aws-sts-tshooting.adoc
Normal file
46
modules/osdk-cco-aws-sts-tshooting.adoc
Normal file
@@ -0,0 +1,46 @@
|
||||
// Module included in the following assemblies:
|
||||
//
|
||||
// * operators/operator_sdk/osdk-token-auth.adoc
|
||||
|
||||
:_content-type: PROCEDURE
|
||||
[id="osdk-cco-aws-sts-tshooting_{context}"]
|
||||
= Troubleshooting
|
||||
|
||||
[id="osdk-cco-aws-sts-tshooting-auth-fail_{context}"]
|
||||
== Authentication failure
|
||||
|
||||
If authentication was not successful, ensure you can assume the role with web identity by using the token provided to the Operator.
|
||||
|
||||
.Procedure
|
||||
|
||||
. Extract the token from the pod:
|
||||
+
|
||||
[source,terminal]
|
||||
----
|
||||
$ oc exec operator-pod -n <namespace_name> \
|
||||
-- cat /var/run/secrets/openshift/serviceaccount/token
|
||||
----
|
||||
|
||||
. Extract the role ARN from the pod:
|
||||
+
|
||||
[source,terminal]
|
||||
----
|
||||
$ oc exec operator-pod -n <namespace_name> \
|
||||
-- cat /<path>/<to>/<secret_name> <1>
|
||||
----
|
||||
<1> Do not use root for the path.
|
||||
|
||||
. Try assuming the role with the web identity token:
|
||||
+
|
||||
[source,terminal]
|
||||
----
|
||||
$ aws sts assume-role-with-web-identity \
|
||||
--role-arn $ROLEARN \
|
||||
--role-session-name <session_name> \
|
||||
--web-identity-token $TOKEN
|
||||
----
|
||||
|
||||
[id="osdk-cco-aws-sts-tshooting-mounting_{context}"]
|
||||
== Secret not mounting correctly
|
||||
|
||||
Pods that run as non-root users cannot write to the `/root` directory where the AWS shared credentials file is expected to exist by default. If the secret is not mounting correctly to the AWS credentials file path, consider mounting the secret to a different location and enabling the shared credentials file option in the AWS SDK.
|
||||
34
modules/osdk-cco-aws-sts.adoc
Normal file
34
modules/osdk-cco-aws-sts.adoc
Normal file
@@ -0,0 +1,34 @@
|
||||
// Module included in the following assemblies:
|
||||
//
|
||||
// * operators/operator_sdk/osdk-token-auth.adoc
|
||||
|
||||
:_content-type: CONCEPT
|
||||
[id="osdk-cco-aws-sts_{context}"]
|
||||
= CCO-based workflow for OLM-managed Operators with AWS STS
|
||||
|
||||
When an {product-title} cluster running on AWS is in Security Token Service (STS) mode, it means the cluster is utilizing features of AWS and {product-title} to use IAM roles at an application level. STS enables applications to provide a JSON Web Token (JWT) that can assume an IAM role.
|
||||
|
||||
The JWT includes an Amazon Resource Name (ARN) for the `sts:AssumeRoleWithWebIdentity` IAM action to allow temporarily-granted permission for the service account. The JWT contains the signing keys for the `ProjectedServiceAccountToken` that AWS IAM can validate. The service account token itself, which is signed, is used as the JWT required for assuming the AWS role.
|
||||
|
||||
The Cloud Credential Operator (CCO) is a cluster Operator installed by default in {product-title} clusters running on cloud providers. For the purposes of STS, the CCO provides the following functions:
|
||||
|
||||
* Detects when it is running on an STS-enabled cluster
|
||||
* Checks for the presence of fields in the `CredentialsRequest` object that provide the required information for granting Operators access to AWS resources
|
||||
|
||||
The CCO performs this detection even when in manual mode. When properly configured, the CCO projects a `Secret` object with the required access information into the Operator namespace.
|
||||
|
||||
Starting in {product-title} 4.14, the CCO can semi-automate this task through an expanded use of `CredentialsRequest` objects, which can request the creation of `Secrets` that contain the information required for STS workflows. Users can provide a role ARN when installing the Operator from either the web console or CLI.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Subscriptions with automatic update approvals are not recommended because there might be permission changes to make prior to updating. Subscriptions with manual update approvals ensure that administrators have the opportunity to verify the permissions of the later version and take any necessary steps prior to update.
|
||||
====
|
||||
|
||||
As an Operator author preparing an Operator for use alongside the updated CCO in {product-title} 4.14, you should instruct users and add code to handle the divergence from earlier CCO versions, in addition to handling STS token authentication (if your Operator is not already STS-enabled). The recommended method is to provide a `CredentialsRequest` object with correctly filled STS-related fields and let the CCO create the `Secret` for you.
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
If you plan to support {product-title} clusters earlier than version 4.14, consider providing users with instructions on how to manually create a secret with the STS-enabling information by using the CCO utility (`ccoctl`). Earlier CCO versions are unaware of STS mode on the cluster and cannot create secrets for you.
|
||||
|
||||
Your code should check for secrets that never appear and warn users to follow the fallback instructions you have provided. For more information, see the "Alternative method" subsection.
|
||||
====
|
||||
@@ -35,8 +35,7 @@ include::modules/osdk-csv-manual-annotations.adoc[leveloffset=+2]
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
* xref:../../operators/operator_sdk/osdk-generating-csvs.adoc#osdk-crds-templates_osdk-generating-csvs[CRD templates]
|
||||
* xref:../../operators/operator_sdk/osdk-generating-csvs.adoc#osdk-init-resource_osdk-generating-csvs[Initializing required custom resources
|
||||
]
|
||||
* xref:../../operators/operator_sdk/osdk-generating-csvs.adoc#osdk-init-resource_osdk-generating-csvs[Initializing required custom resources]
|
||||
* xref:../../operators/operator_sdk/osdk-generating-csvs.adoc#osdk-suggested-namespace_osdk-generating-csvs[Setting a suggested namespace]
|
||||
* xref:../../operators/operator_sdk/osdk-generating-csvs.adoc#osdk-suggested-namespace-default-node_osdk-generating-csvs[Setting a suggested namespace with default node selector]
|
||||
* xref:../../operators/operator_sdk/osdk-generating-csvs.adoc#olm-enabling-operator-for-restricted-network_osdk-generating-csvs[Enabling your Operator for restricted network environments] (disconnected mode)
|
||||
|
||||
33
operators/operator_sdk/osdk-token-auth.adoc
Normal file
33
operators/operator_sdk/osdk-token-auth.adoc
Normal file
@@ -0,0 +1,33 @@
|
||||
:_content-type: ASSEMBLY
|
||||
[id="osdk-token-auth"]
|
||||
= Token authentication for Operators on cloud providers
|
||||
include::_attributes/common-attributes.adoc[]
|
||||
:context: osdk-token-auth
|
||||
|
||||
toc::[]
|
||||
|
||||
Many cloud providers can enable authentication by using account tokens that provide short-term, limited-privilege security credentials.
|
||||
|
||||
{product-title} includes the Cloud Credential Operator (CCO) to manage cloud provider credentials as custom resource definitions (CRDs). The CCO syncs on `CredentialsRequest` custom resources (CRs) to allow {product-title} components to request cloud provider credentials with any specific permissions required.
|
||||
|
||||
Previously, on clusters where the CCO is in _manual mode_, Operators managed by Operator Lifecycle Manager (OLM) often provided detailed instructions in the OperatorHub for how users could manually provision any required cloud credentials.
|
||||
|
||||
Starting in {product-title} 4.14, the CCO can detect when it is running on clusters enabled to use short-term credentials on certain cloud providers. It can then semi-automate provisioning certain credentials, provided that the Operator author has enabled their Operator to support the updated CCO.
|
||||
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
|
||||
* xref:../../authentication/managing_cloud_provider_credentials/about-cloud-credential-operator.adoc#about-cloud-credential-operator[About the Cloud Credential Operator]
|
||||
|
||||
include::modules/osdk-cco-aws-sts.adoc[leveloffset=+1]
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
|
||||
* xref:../../authentication/managing_cloud_provider_credentials/cco-short-term-creds.adoc#cco-short-term-creds-aws-olm_cco-short-term-creds[OLM-managed Operator support for authentication with AWS STS]
|
||||
* xref:../../operators/admin/olm-adding-operators-to-cluster.adoc#olm-installing-from-operatorhub-using-web-console_olm-adding-operators-to-a-cluster[Installing from OperatorHub using the web console]
|
||||
* xref:../../operators/admin/olm-adding-operators-to-cluster.adoc#olm-installing-operator-from-operatorhub-using-cli_olm-adding-operators-to-a-cluster[Installing from OperatorHub using the CLI]
|
||||
|
||||
include::modules/osdk-cco-aws-sts-enabling.adoc[leveloffset=+2]
|
||||
include::modules/osdk-cco-aws-sts-role.adoc[leveloffset=+2]
|
||||
include::modules/osdk-cco-aws-sts-tshooting.adoc[leveloffset=+2]
|
||||
include::modules/osdk-cco-aws-sts-alt.adoc[leveloffset=+2]
|
||||
Reference in New Issue
Block a user