From 71753e21e0d78a986b21a773bdf3fbaf7333879c Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 4 Nov 2020 13:06:05 -0800 Subject: [PATCH] add missing TTL for STS credentials on etcd (#10828) --- cmd/etcd.go | 16 +++++++++++++++- cmd/iam-etcd-store.go | 12 ++++++------ cmd/iam-object-store.go | 10 +++++----- cmd/iam.go | 17 ++++++++++++----- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/cmd/etcd.go b/cmd/etcd.go index 828748f91..2985eae01 100644 --- a/cmd/etcd.go +++ b/cmd/etcd.go @@ -38,9 +38,23 @@ func etcdErrToErr(err error, etcdEndpoints []string) error { } } -func saveKeyEtcd(ctx context.Context, client *etcd.Client, key string, data []byte) error { +func saveKeyEtcdWithTTL(ctx context.Context, client *etcd.Client, key string, data []byte, ttl int64) error { timeoutCtx, cancel := context.WithTimeout(ctx, defaultContextTimeout) defer cancel() + lease, err := client.Grant(timeoutCtx, ttl) + if err != nil { + return etcdErrToErr(err, client.Endpoints()) + } + _, err = client.Put(timeoutCtx, key, string(data), etcd.WithLease(lease.ID)) + return etcdErrToErr(err, client.Endpoints()) +} + +func saveKeyEtcd(ctx context.Context, client *etcd.Client, key string, data []byte, opts ...options) error { + timeoutCtx, cancel := context.WithTimeout(ctx, defaultContextTimeout) + defer cancel() + if len(opts) > 0 { + return saveKeyEtcdWithTTL(ctx, client, key, data, opts[0].ttl) + } _, err := client.Put(timeoutCtx, key, string(data)) return etcdErrToErr(err, client.Endpoints()) } diff --git a/cmd/iam-etcd-store.go b/cmd/iam-etcd-store.go index 7d4febcfe..716b6e7ab 100644 --- a/cmd/iam-etcd-store.go +++ b/cmd/iam-etcd-store.go @@ -99,7 +99,7 @@ func (ies *IAMEtcdStore) runlock() { ies.RUnlock() } -func (ies *IAMEtcdStore) saveIAMConfig(ctx context.Context, item interface{}, path string) error { +func (ies *IAMEtcdStore) saveIAMConfig(ctx context.Context, item interface{}, path string, opts ...options) error { data, err := json.Marshal(item) if err != nil { return err @@ -110,7 +110,7 @@ func (ies *IAMEtcdStore) saveIAMConfig(ctx context.Context, item interface{}, pa return err } } - return saveKeyEtcd(ctx, ies.client, path, data) + return saveKeyEtcd(ctx, ies.client, path, data, opts...) } func (ies *IAMEtcdStore) loadIAMConfig(ctx context.Context, item interface{}, path string) error { @@ -566,12 +566,12 @@ func (ies *IAMEtcdStore) savePolicyDoc(ctx context.Context, policyName string, p return ies.saveIAMConfig(ctx, &p, getPolicyDocPath(policyName)) } -func (ies *IAMEtcdStore) saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error { - return ies.saveIAMConfig(ctx, mp, getMappedPolicyPath(name, userType, isGroup)) +func (ies *IAMEtcdStore) saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy, opts ...options) error { + return ies.saveIAMConfig(ctx, mp, getMappedPolicyPath(name, userType, isGroup), opts...) } -func (ies *IAMEtcdStore) saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity) error { - return ies.saveIAMConfig(ctx, u, getUserIdentityPath(name, userType)) +func (ies *IAMEtcdStore) saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity, opts ...options) error { + return ies.saveIAMConfig(ctx, u, getUserIdentityPath(name, userType), opts...) } func (ies *IAMEtcdStore) saveGroupInfo(ctx context.Context, name string, gi GroupInfo) error { diff --git a/cmd/iam-object-store.go b/cmd/iam-object-store.go index af1bb21ca..ce2f4a990 100644 --- a/cmd/iam-object-store.go +++ b/cmd/iam-object-store.go @@ -204,7 +204,7 @@ func (iamOS *IAMObjectStore) migrateBackendFormat(ctx context.Context) error { return iamOS.migrateToV1(ctx) } -func (iamOS *IAMObjectStore) saveIAMConfig(ctx context.Context, item interface{}, path string) error { +func (iamOS *IAMObjectStore) saveIAMConfig(ctx context.Context, item interface{}, path string, opts ...options) error { data, err := json.Marshal(item) if err != nil { return err @@ -512,12 +512,12 @@ func (iamOS *IAMObjectStore) savePolicyDoc(ctx context.Context, policyName strin return iamOS.saveIAMConfig(ctx, &p, getPolicyDocPath(policyName)) } -func (iamOS *IAMObjectStore) saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error { - return iamOS.saveIAMConfig(ctx, mp, getMappedPolicyPath(name, userType, isGroup)) +func (iamOS *IAMObjectStore) saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy, opts ...options) error { + return iamOS.saveIAMConfig(ctx, mp, getMappedPolicyPath(name, userType, isGroup), opts...) } -func (iamOS *IAMObjectStore) saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity) error { - return iamOS.saveIAMConfig(ctx, u, getUserIdentityPath(name, userType)) +func (iamOS *IAMObjectStore) saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity, opts ...options) error { + return iamOS.saveIAMConfig(ctx, u, getUserIdentityPath(name, userType), opts...) } func (iamOS *IAMObjectStore) saveGroupInfo(ctx context.Context, name string, gi GroupInfo) error { diff --git a/cmd/iam.go b/cmd/iam.go index 69656d5fe..c7500dc9a 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -230,6 +230,11 @@ const ( srvAccUser ) +// key options +type options struct { + ttl int64 //expiry in seconds +} + // IAMStorageAPI defines an interface for the IAM persistence layer type IAMStorageAPI interface { lock() @@ -254,13 +259,13 @@ type IAMStorageAPI interface { loadAll(context.Context, *IAMSys) error - saveIAMConfig(ctx context.Context, item interface{}, path string) error + saveIAMConfig(ctx context.Context, item interface{}, path string, opts ...options) error loadIAMConfig(ctx context.Context, item interface{}, path string) error deleteIAMConfig(ctx context.Context, path string) error savePolicyDoc(ctx context.Context, policyName string, p iampolicy.Policy) error - saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy) error - saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity) error + saveMappedPolicy(ctx context.Context, name string, userType IAMUserType, isGroup bool, mp MappedPolicy, opts ...options) error + saveUserIdentity(ctx context.Context, name string, userType IAMUserType, u UserIdentity, opts ...options) error saveGroupInfo(ctx context.Context, group string, gi GroupInfo) error deletePolicyDoc(ctx context.Context, policyName string) error @@ -703,6 +708,8 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa sys.store.lock() defer sys.store.unlock() + ttl := int64(UTCNow().Sub(cred.Expiration).Seconds()) + // If OPA is not set we honor any policy claims for this // temporary user which match with pre-configured canned // policies for this server. @@ -727,7 +734,7 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa return nil } - if err := sys.store.saveMappedPolicy(context.Background(), accessKey, stsUser, false, mp); err != nil { + if err := sys.store.saveMappedPolicy(context.Background(), accessKey, stsUser, false, mp, options{ttl: ttl}); err != nil { return err } @@ -735,7 +742,7 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa } u := newUserIdentity(cred) - if err := sys.store.saveUserIdentity(context.Background(), accessKey, stsUser, u); err != nil { + if err := sys.store.saveUserIdentity(context.Background(), accessKey, stsUser, u, options{ttl: ttl}); err != nil { return err }