@@ -11,6 +11,7 @@ import (
11
11
"encoding/base64"
12
12
"fmt"
13
13
"os"
14
+ "regexp"
14
15
"strings"
15
16
"sync"
16
17
"time"
@@ -141,16 +142,21 @@ type ECRAuthenticator struct {
141
142
ecrAuthLock sync.Mutex
142
143
}
143
144
145
+ const (
146
+ // ECR tokens are valid for 12h [1], and we want to ensure we refresh at least twice a day before full expiry.
147
+ //
148
+ // [1] https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html
149
+ ecrTokenRefreshTime = 4 * time .Hour
150
+ )
151
+
144
152
func (ath * ECRAuthenticator ) Authenticate (ctx context.Context , registry string ) (auth * Authentication , err error ) {
145
- // TODO(cw): find better way to detect if ref is an ECR repo
146
- if ! strings .Contains (registry , ".dkr." ) || ! strings .Contains (registry , ".amazonaws.com" ) {
153
+ if ! isECRRegistry (registry ) {
147
154
return nil , nil
148
155
}
149
156
150
157
ath .ecrAuthLock .Lock ()
151
158
defer ath .ecrAuthLock .Unlock ()
152
- // ECR tokens are valid for 12h: https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html
153
- if time .Since (ath .ecrAuthLastRefreshTime ) > 10 * time .Hour {
159
+ if time .Since (ath .ecrAuthLastRefreshTime ) > ecrTokenRefreshTime {
154
160
tknout , err := ath .ecrc .GetAuthorizationToken (ctx , & ecr.GetAuthorizationTokenInput {})
155
161
if err != nil {
156
162
return nil , err
@@ -193,6 +199,13 @@ func (a *Authentication) Empty() bool {
193
199
return false
194
200
}
195
201
202
+ var ecrRegistryRegexp = regexp .MustCompile (`\d{12}.dkr.ecr.\w+-\w+-\w+.amazonaws.com` )
203
+
204
+ // isECRRegistry returns true if the registry domain is an ECR registry
205
+ func isECRRegistry (domain string ) bool {
206
+ return ecrRegistryRegexp .MatchString (domain )
207
+ }
208
+
196
209
// AllowedAuthFor describes for which repositories authentication may be provided for
197
210
type AllowedAuthFor struct {
198
211
All bool
@@ -293,7 +306,7 @@ func (a AllowedAuthFor) GetAuthFor(ctx context.Context, auth RegistryAuthenticat
293
306
// If we haven't found authentication using the built-in way, we'll resort to additional auth
294
307
// the user sent us.
295
308
defer func () {
296
- if err != nil || ( res != nil && ( res .Auth != "" || res . Password != "" ) ) {
309
+ if err != nil || ! res .Empty ( ) {
297
310
return
298
311
}
299
312
@@ -306,10 +319,15 @@ func (a AllowedAuthFor) GetAuthFor(ctx context.Context, auth RegistryAuthenticat
306
319
}()
307
320
308
321
var regAllowed bool
309
- if a .IsAllowAll () {
322
+ switch {
323
+ case a .IsAllowAll ():
310
324
// free for all
311
325
regAllowed = true
312
- } else {
326
+ case isECRRegistry (reg ):
327
+ // We allow ECR registries by default to support private ECR registries OOTB.
328
+ // The AWS IAM permissions dictate what users actually have access to.
329
+ regAllowed = true
330
+ default :
313
331
for _ , a := range a .Explicit {
314
332
if a == reg {
315
333
regAllowed = true
0 commit comments