mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
fix: verify caller-supplied role ARNs against the stored canonical ARN (#972)
This commit is contained in:
@@ -21,7 +21,7 @@ require (
|
||||
github.com/jackc/pgx/v5 v5.10.0
|
||||
github.com/klauspost/cpuid/v2 v2.4.0
|
||||
github.com/miekg/dns v1.1.73
|
||||
github.com/mulgadc/bluebottle v1.18.1-0.20260827045410-e7d5cf022748
|
||||
github.com/mulgadc/bluebottle v1.18.1-0.20260901051501-b00bc7828992
|
||||
github.com/mulgadc/northstar v1.18.0
|
||||
github.com/mulgadc/predastore v1.18.1-0.20260831064140-ff6a1dc42441
|
||||
github.com/mulgadc/viperblock v1.18.0
|
||||
@@ -119,7 +119,7 @@ require (
|
||||
github.com/google/go-tpm v0.9.8 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gookit/color v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-metrics v0.5.4 // indirect
|
||||
@@ -184,14 +184,14 @@ require (
|
||||
go.etcd.io/bbolt v1.4.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.70.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.21.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.21.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/log v0.21.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.71.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.22.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.22.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/log v0.22.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.11.0 // indirect
|
||||
go.uber.org/nilaway v0.0.0-20260721205819-4a0f7653488a // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||
@@ -202,10 +202,10 @@ require (
|
||||
golang.org/x/term v0.45.0 // indirect
|
||||
golang.org/x/text v0.41.0 // indirect
|
||||
golang.org/x/vuln v1.6.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect
|
||||
google.golang.org/grpc v1.83.0 // indirect
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 // indirect
|
||||
google.golang.org/grpc v1.83.1 // indirect
|
||||
google.golang.org/protobuf v1.36.12 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||
tags.cncf.io/container-device-interface v1.1.0 // indirect
|
||||
|
||||
@@ -1105,8 +1105,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9K
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 h1:/Tnpcb2E0Pz/tN9s3bfEY2Q8ePCEX9iuS+cneUwncnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0/go.mod h1:zOBXOsUaBSjKgmH4OGzV1esUpR3oUSCPYVd2cUBjKYY=
|
||||
github.com/hamba/avro/v2 v2.17.2/go.mod h1:Q9YK+qxAhtVrNqOhwlZTATLgLA8qxG2vtvkhK8fJ7Jo=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
@@ -1327,8 +1327,8 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
|
||||
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
|
||||
github.com/mulgadc/bluebottle v1.18.1-0.20260827045410-e7d5cf022748 h1:kvoYwPtGXrX7GTN1aRL9KteP0bteaYNzrSMFQ+A7AmU=
|
||||
github.com/mulgadc/bluebottle v1.18.1-0.20260827045410-e7d5cf022748/go.mod h1:mvvV4d2w+kGLXxO1ymptNlxqUlNJKB2oAhk6PkpVLj8=
|
||||
github.com/mulgadc/bluebottle v1.18.1-0.20260901051501-b00bc7828992 h1:ss5/vEr5STIZXBWAZZthlAS6q9i44aOMbaFjZL9ediY=
|
||||
github.com/mulgadc/bluebottle v1.18.1-0.20260901051501-b00bc7828992/go.mod h1:XBIMI+G2s3wuJNiEdYtlGDvCacw82OXEw50RIQhowYg=
|
||||
github.com/mulgadc/northstar v1.18.0 h1:ksRjIKE6qtrw/ZoYaJh8JRBh+xdnuDw8FsmFLFCiXbg=
|
||||
github.com/mulgadc/northstar v1.18.0/go.mod h1:z6iol77R1vsIQyIBc1JQboUPhSJ6eG4bipzfbZZbLEM=
|
||||
github.com/mulgadc/predastore v1.18.1-0.20260831064140-ff6a1dc42441 h1:5t+iuKpnRWXkKOmh5lLBoziBaWD+H71edWO/O4ceMp8=
|
||||
@@ -1639,8 +1639,8 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.0 h1:oEl2Pw/i4OQwhAuda2pAHFAcOMivA+Xa+iTccBfab/g=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.0/go.mod h1:yMSQaiiq5dpfrSJCYLBcqFeJkFFI67seT4ngvx6jfVo=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.1 h1:5sHc4ToTFjfSZCtGAAM6jPunICAmJX73htv372T4ipc=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.1/go.mod h1:oa6kgvyz/3GYW04dohd0++xJIH4xdQY8PAbpeCMaM8M=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.28.0/go.mod h1:9BIqH22qyHWAiZxQh0whuJygro59z+nbMVuc7ciiGug=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.29.0/go.mod h1:GW2aWZNwR2ZxDLdv8OyC2G8zkRoQBuURgV7RPQgcPoU=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.31.0/go.mod h1:tzQL6E1l+iV44YFTkcAeNQqzXUiekSYP9jjJjXwEd00=
|
||||
@@ -1678,8 +1678,8 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0 h1:3g7B90UzBltIDKq1/5mrTGxTnOFDV0ICOhLoxiZ8jlg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0/go.mod h1:Ef8SuTh59BT7+ofpDxN9z+yOlc4t2GjLmKDgYNJL/NU=
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.70.0 h1:1+WLVYezXA9tkuVzKQri8zgB1cEIVYKUSoYIRjsBiMU=
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.70.0/go.mod h1:rbAXUUXqQDMxpSnmof4VtcZ+7YpZQEtjXSCIfdvR0Go=
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.71.0 h1:v4KkRLVvE1cWqTJDfZZkTCG+Z4aolsa6RVos0FX7vqE=
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.71.0/go.mod h1:g/xbuPC0XbgwMdKuyF5sKOUUEsorSkN6APydyFP/H9E=
|
||||
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
|
||||
@@ -1704,21 +1704,21 @@ go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1sp
|
||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||
go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc=
|
||||
go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.21.0 h1:WseeVYf5dJZTsyPiyW5L14k5qsSibqXAMTSiFEDiWr0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.21.0/go.mod h1:SiLZnQS6Qk2eCpvr2CH/XMAOa64TWGXxEZJZCpD2Lmc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 h1:klTViGcsvLCd1xN3rZzfZ12NslC/OimbmR+k+A006RI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0/go.mod h1:jRsK04CWmXuY8A0O+wMpSf+t90RHZ53o5Qmxn2PQPfk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.22.0 h1:Bu39F5tzJct+f2IZbB8989fwyTps3c8e7EsUQsz+vs8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.22.0/go.mod h1:dJUwod88EsFgYCqrDHaSPzhiY9pBUpt0d85/qSfua7k=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.46.0 h1:qkDYCAFiZXLcs1L4aY+tP2wguQ4kURANqHOQMA2et2s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.46.0/go.mod h1:tkipS4DRzmpAmvg+Gw4++O1IdDq6TVDnvnYU6cmbQVs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 h1:OFnwLJr+pF3iHrlGSzbxyuo6/6HyBlnlN1CWEJmBVcw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0/go.mod h1:716wFneO0ov19A2beH5hjfh9AK5z/VWNAtDijp1Y0/g=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 h1:w53CDeOA/Kurp7yRsegSr6pbbr759dOvJ+yNmWM6Hxs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0/go.mod h1:BOmGMCbAtvcJiSJ+hLuhgPLdDbimnraSl8irz3iY8sY=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0/go.mod h1:U2R3XyVPzn0WX7wOIypPuptulsMcPDPs/oiSVOMVnHY=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw=
|
||||
go.opentelemetry.io/otel/log v0.21.0 h1:SLsVDGmtyBrdw8/a2Z0bOIxou/+bN4z56GebH7T0LvA=
|
||||
go.opentelemetry.io/otel/log v0.21.0/go.mod h1:iReetQrZL9Wyg84cCkOoCmqDHS5RCFfyxC7J+r8fn8g=
|
||||
go.opentelemetry.io/otel/log v0.22.0 h1:5DBNnfvaJ6CVdkJ+Jle8Tzs50aSSv49TXGj9XRsEYw0=
|
||||
go.opentelemetry.io/otel/log v0.22.0/go.mod h1:gzOt/R67vF2GniAqWu8Qv0SXy89f71muHcrkz76PCdc=
|
||||
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
|
||||
@@ -1769,10 +1769,10 @@ go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg
|
||||
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
||||
go.opentelemetry.io/otel/sdk v1.46.0 h1:h5CNQQjEbuQXY/JfZtgt3i7HVFV3aHPO2OAwO2eTYPI=
|
||||
go.opentelemetry.io/otel/sdk v1.46.0/go.mod h1:GAERFXFt5SYCEB+YiKUbMBeza6UaDH7GmGOZEfh2gSM=
|
||||
go.opentelemetry.io/otel/sdk/log v0.21.0 h1:QsE7XSR0ktQdKmRKGnR+f1ObGF32WG+7MER/P9KgmYc=
|
||||
go.opentelemetry.io/otel/sdk/log v0.21.0/go.mod h1:m9mApjCoD2/1QuKCAptjv+BrG9WKOvQLVdNx+iBldTo=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.21.0 h1:X+JBBgKlswCGYsmgL0CnoUUtlE//VB345c84jYAYkdQ=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.21.0/go.mod h1:HD1575K8e6sIFBBDd5tZB3t9DlMytWXq9FuR+Y4rfjE=
|
||||
go.opentelemetry.io/otel/sdk/log v0.22.0 h1:PRL+s6P63XT4E/bheEflopPUpVxuvANqZwtt89yhoGk=
|
||||
go.opentelemetry.io/otel/sdk/log v0.22.0/go.mod h1:JNp0sBELrjCTcu5W3GzABVypeU6vDJjBS+X0JISuz+g=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.22.0 h1:infPnfNrhCNgOUZRs3gWUg8vhoBUHihq02gwK05gzlg=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.22.0/go.mod h1:gkQZA3z15Bv3KU9vigBTi8dFechSozRP7v94X4VZv+s=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y=
|
||||
@@ -2849,8 +2849,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260511170946-3700d4141b60/go.
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260519071638-aa98bba5eb94/go.mod h1:1dCETSCY2YKZNXQE3h4fun3TYwF5p8jejRKZgfWAgAY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260618152121-87f3d3e198d3/go.mod h1:Z4WJ5pJOYWFWcHEQUelD5QaZDknIQkpIL/+fyJOT9+A=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d h1:FarXi840EJWSHYTN3ERkADbPWjl307+FGrA22KAVjjc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 h1:ax2KzoSRIZU/M0cIxri3pKxy99vniH1PVxWC6si/eZI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688/go.mod h1:1RJ9BQGyNdZwkGc1eTqkErfRZ6RJyYPHZo73BZ1vQqI=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:+34luvCflYKiKylNwGJfn9cFBbcL/WrkciMmDmsTQ/A=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw=
|
||||
@@ -3031,8 +3031,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68/go.
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260618152121-87f3d3e198d3/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 h1:cYNAzI2sUwhmCcoj9TxvihSrqsxt6uIkj3rDRhSDmW4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
@@ -3126,8 +3126,8 @@ google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhH
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
||||
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
|
||||
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
|
||||
google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y=
|
||||
google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=
|
||||
google.golang.org/grpc/examples v0.0.0-20201112215255-90f1b3ee835b/go.mod h1:IBqQ7wSUJ2Ep09a8rMWFsg4fmI2r38zwsq8a0GgxXpM=
|
||||
@@ -3171,8 +3171,8 @@ google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXn
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -89,7 +89,7 @@ func newEKSServiceFixture(t *testing.T) *eksServiceFixture {
|
||||
VPCSG: sg,
|
||||
VPCK3s: vpc,
|
||||
VPCSubnet: fakeSubnetResolver{},
|
||||
IAM: newFakeEnsurer(),
|
||||
IAM: newEnsurerWithRole("eks-node", fixtureNodeRoleARN),
|
||||
NLB: nlb,
|
||||
Instance: inst,
|
||||
Image: ami,
|
||||
|
||||
@@ -706,15 +706,26 @@ func gatewayHostIP(gatewayURL string) string {
|
||||
// provider, mirroring the implicit instance profile real EKS creates for a node
|
||||
// role. Idempotent: concurrent worker launches converge on the same profile.
|
||||
func (s *EKSServiceImpl) ensureNodeInstanceProfile(accountID, nodeRoleARN string) (string, error) {
|
||||
roleAccount, roleName, err := auth.ParseRoleARN(nodeRoleARN)
|
||||
// Resolution compares the supplied ARN against the stored one, so an invented
|
||||
// path cannot bind a profile to the role its trailing name happens to match.
|
||||
_, roleName, err := auth.ResolveRoleARN(nodeRoleARN, func(account, name string) (string, error) {
|
||||
// The profile is created under the caller's account, so a role from
|
||||
// another account would silently bind a name that account does not own.
|
||||
if account != accountID {
|
||||
return "", fmt.Errorf("is not in account %s", accountID)
|
||||
}
|
||||
out, gerr := s.iamEnsurer().GetRole(account, &iam.GetRoleInput{RoleName: aws.String(name)})
|
||||
if gerr != nil {
|
||||
return "", gerr
|
||||
}
|
||||
if out == nil || out.Role == nil {
|
||||
return "", nil
|
||||
}
|
||||
return aws.StringValue(out.Role.Arn), nil
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("node role ARN %q: %w", nodeRoleARN, err)
|
||||
}
|
||||
// The profile is created under the caller's account, so a role from another
|
||||
// account would silently bind a name that account does not own.
|
||||
if roleAccount != accountID {
|
||||
return "", fmt.Errorf("node role ARN %q is not in account %s", nodeRoleARN, accountID)
|
||||
}
|
||||
profileName := roleName
|
||||
|
||||
out, err := s.iamEnsurer().GetInstanceProfile(accountID, &iam.GetInstanceProfileInput{
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/mulgadc/bluebottle/pkg/auth"
|
||||
"github.com/mulgadc/spinifex/spinifex/awserrors"
|
||||
iammock "github.com/mulgadc/spinifex/spinifex/handlers/iam/mock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -20,8 +21,20 @@ func newFakeEnsurer() *iammock.SystemInstanceRoleEnsurer {
|
||||
|
||||
const testNodeRoleARN = "arn:aws:iam::000000000001:role/eks-quickstart-node-role"
|
||||
|
||||
func TestEnsureNodeInstanceProfile_CreatesAndAttaches(t *testing.T) {
|
||||
// fixtureNodeRoleARN is the node role the shared service fixture's nodegroups
|
||||
// launch with; resolution requires it to exist in the mock's IAM.
|
||||
const fixtureNodeRoleARN = "arn:aws:iam::111122223333:role/eks-node"
|
||||
|
||||
// newEnsurerWithRole returns a mock holding roleName with the canonical ARN IAM
|
||||
// would have stored for it, which node role resolution verifies against.
|
||||
func newEnsurerWithRole(roleName, roleARN string) *iammock.SystemInstanceRoleEnsurer {
|
||||
f := newFakeEnsurer()
|
||||
f.Roles[roleName] = &iam.Role{RoleName: aws.String(roleName), Arn: aws.String(roleARN)}
|
||||
return f
|
||||
}
|
||||
|
||||
func TestEnsureNodeInstanceProfile_CreatesAndAttaches(t *testing.T) {
|
||||
f := newEnsurerWithRole("eks-quickstart-node-role", testNodeRoleARN)
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
|
||||
arn, err := s.ensureNodeInstanceProfile("000000000001", testNodeRoleARN)
|
||||
@@ -33,7 +46,7 @@ func TestEnsureNodeInstanceProfile_CreatesAndAttaches(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEnsureNodeInstanceProfile_ExistingWithRoleIsNoop(t *testing.T) {
|
||||
f := newFakeEnsurer()
|
||||
f := newEnsurerWithRole("eks-quickstart-node-role", testNodeRoleARN)
|
||||
f.Profiles["eks-quickstart-node-role"] = &iam.InstanceProfile{
|
||||
InstanceProfileName: aws.String("eks-quickstart-node-role"),
|
||||
Arn: aws.String("arn:aws:iam::000000000001:instance-profile/eks-quickstart-node-role"),
|
||||
@@ -49,7 +62,7 @@ func TestEnsureNodeInstanceProfile_ExistingWithRoleIsNoop(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEnsureNodeInstanceProfile_ExistingWithoutRoleAttaches(t *testing.T) {
|
||||
f := newFakeEnsurer()
|
||||
f := newEnsurerWithRole("eks-quickstart-node-role", testNodeRoleARN)
|
||||
f.Profiles["eks-quickstart-node-role"] = &iam.InstanceProfile{
|
||||
InstanceProfileName: aws.String("eks-quickstart-node-role"),
|
||||
Arn: aws.String("arn:aws:iam::000000000001:instance-profile/eks-quickstart-node-role"),
|
||||
@@ -63,7 +76,7 @@ func TestEnsureNodeInstanceProfile_ExistingWithoutRoleAttaches(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEnsureNodeInstanceProfile_AddRoleLimitExceededIsSuccess(t *testing.T) {
|
||||
f := newFakeEnsurer()
|
||||
f := newEnsurerWithRole("eks-quickstart-node-role", testNodeRoleARN)
|
||||
f.AddRoleToInstanceProfileErr = errors.New(awserrors.ErrorIAMLimitExceeded)
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
|
||||
@@ -75,7 +88,7 @@ func TestEnsureNodeInstanceProfile_AddRoleLimitExceededIsSuccess(t *testing.T) {
|
||||
// A path-bearing role ARN names its profile after the final segment only; the
|
||||
// path is not a legal instance-profile name character.
|
||||
func TestEnsureNodeInstanceProfile_PathBearingRoleUsesFinalSegment(t *testing.T) {
|
||||
f := newFakeEnsurer()
|
||||
f := newEnsurerWithRole("Worker", "arn:aws:iam::000000000001:role/team/Worker")
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
|
||||
arn, err := s.ensureNodeInstanceProfile("000000000001", "arn:aws:iam::000000000001:role/team/Worker")
|
||||
@@ -94,11 +107,10 @@ func TestEnsureNodeInstanceProfile_RejectsInvalidARNs(t *testing.T) {
|
||||
"non-role resource": "arn:aws:iam::000000000001:user/bob",
|
||||
"empty role name": "arn:aws:iam::000000000001:role/",
|
||||
"empty account": "arn:aws:iam:::role/Worker",
|
||||
"cross-account": "arn:aws:iam::000000000002:role/Worker",
|
||||
}
|
||||
for name, arn := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
f := newFakeEnsurer()
|
||||
f := newEnsurerWithRole("Worker", "arn:aws:iam::000000000001:role/Worker")
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
_, err := s.ensureNodeInstanceProfile("000000000001", arn)
|
||||
require.Error(t, err)
|
||||
@@ -107,3 +119,53 @@ func TestEnsureNodeInstanceProfile_RejectsInvalidARNs(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// A role another account owns is rejected by the account guard alone: the mock
|
||||
// holds it under the ARN the caller supplied, so the canonical comparison would
|
||||
// pass and only the guard can refuse it.
|
||||
func TestEnsureNodeInstanceProfile_RejectsCrossAccountRole(t *testing.T) {
|
||||
const crossAccountARN = "arn:aws:iam::000000000002:role/Worker"
|
||||
f := newEnsurerWithRole("Worker", crossAccountARN)
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
|
||||
_, err := s.ensureNodeInstanceProfile("000000000001", crossAccountARN)
|
||||
require.Error(t, err)
|
||||
assert.NotErrorIs(t, err, auth.ErrRoleARNMismatch, "the guard must reject, not the ARN comparison")
|
||||
assert.ErrorContains(t, err, "is not in account 000000000001")
|
||||
assert.Zero(t, f.CreateInstanceProfileCalls)
|
||||
assert.Zero(t, f.AddRoleToInstanceProfileCalls)
|
||||
}
|
||||
|
||||
// A node role ARN carrying a path the stored role does not have must not bind a
|
||||
// profile to the role its final segment names.
|
||||
func TestEnsureNodeInstanceProfile_RejectsFabricatedPath(t *testing.T) {
|
||||
f := newEnsurerWithRole("eks-quickstart-node-role", testNodeRoleARN)
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
|
||||
_, err := s.ensureNodeInstanceProfile("000000000001",
|
||||
"arn:aws:iam::000000000001:role/decoy/eks-quickstart-node-role")
|
||||
require.ErrorIs(t, err, auth.ErrRoleARNMismatch)
|
||||
assert.Zero(t, f.CreateInstanceProfileCalls)
|
||||
assert.Zero(t, f.AddRoleToInstanceProfileCalls)
|
||||
}
|
||||
|
||||
// A pathed role is likewise not reachable by its pathless ARN.
|
||||
func TestEnsureNodeInstanceProfile_RejectsStrippedPath(t *testing.T) {
|
||||
f := newEnsurerWithRole("Worker", "arn:aws:iam::000000000001:role/team/Worker")
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
|
||||
_, err := s.ensureNodeInstanceProfile("000000000001", "arn:aws:iam::000000000001:role/Worker")
|
||||
require.ErrorIs(t, err, auth.ErrRoleARNMismatch)
|
||||
assert.Zero(t, f.CreateInstanceProfileCalls)
|
||||
}
|
||||
|
||||
// A node role that does not exist in IAM cannot be resolved, so no profile is
|
||||
// created for it.
|
||||
func TestEnsureNodeInstanceProfile_RejectsUnknownRole(t *testing.T) {
|
||||
f := newFakeEnsurer()
|
||||
s := &EKSServiceImpl{deps: EKSServiceDeps{IAM: f}}
|
||||
|
||||
_, err := s.ensureNodeInstanceProfile("000000000001", testNodeRoleARN)
|
||||
require.Error(t, err)
|
||||
assert.Zero(t, f.CreateInstanceProfileCalls)
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ func createNGInput(cluster, ng string, desired int64) *eks.CreateNodegroupInput
|
||||
return &eks.CreateNodegroupInput{
|
||||
ClusterName: aws.String(cluster),
|
||||
NodegroupName: aws.String(ng),
|
||||
NodeRole: aws.String("arn:aws:iam::111122223333:role/eks-node"),
|
||||
NodeRole: aws.String(fixtureNodeRoleARN),
|
||||
Subnets: aws.StringSlice([]string{"subnet-aaa"}),
|
||||
ScalingConfig: &eks.NodegroupScalingConfig{
|
||||
MinSize: aws.Int64(1),
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/nats-io/nats.go/jetstream"
|
||||
@@ -49,7 +48,10 @@ func (s *STSServiceImpl) AssumeRoleWithWebIdentity(input *sts.AssumeRoleWithWebI
|
||||
return nil, errors.New(awserrors.ErrorPackedPolicyTooLarge)
|
||||
}
|
||||
|
||||
roleAccountID, roleName, err := auth.ParseRoleARN(roleARN)
|
||||
// Only the account is taken here: webIdentityKeyFunc needs it before the
|
||||
// token is verified, and resolving the role would put an IAM read ahead of
|
||||
// verification. The full ARN is verified below.
|
||||
roleAccountID, _, err := auth.ParseRoleARN(roleARN)
|
||||
if err != nil {
|
||||
return nil, errors.New(awserrors.ErrorValidationError)
|
||||
}
|
||||
@@ -77,15 +79,15 @@ func (s *STSServiceImpl) AssumeRoleWithWebIdentity(input *sts.AssumeRoleWithWebI
|
||||
return nil, errors.New(awserrors.ErrorInvalidIdentityToken)
|
||||
}
|
||||
|
||||
roleOut, err := s.iamSvc.GetRole(roleAccountID, &iam.GetRoleInput{RoleName: aws.String(roleName)})
|
||||
_, role, err := ResolveRoleByARN(s.iamSvc, roleARN)
|
||||
if err != nil {
|
||||
// All misses → AccessDenied to prevent cross-account role enumeration.
|
||||
if err.Error() == awserrors.ErrorIAMNoSuchEntity {
|
||||
// A supplied ARN that is not the stored one is one of those misses.
|
||||
if errors.Is(err, ErrRoleUnresolved) {
|
||||
return nil, errors.New(awserrors.ErrorAccessDenied)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
role := roleOut.Role
|
||||
|
||||
duration := defaultDurationSeconds
|
||||
if input.DurationSeconds != nil {
|
||||
|
||||
@@ -616,3 +616,30 @@ func TestJWKToECDSAPublicKey_RejectsUnsupportedShapes(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// A RoleArn carrying a path the stored role does not have must not reach the
|
||||
// role its final segment names, even when the token and trust policy are valid.
|
||||
func TestAssumeRoleWithWebIdentity_RejectsFabricatedPath(t *testing.T) {
|
||||
svc, _ := newTestSetup(t)
|
||||
f := newWebIdentityFixture(t, svc, testCallerAccountID)
|
||||
role := createRoleForFixture(t, svc, testCallerAccountID, "irsa-app",
|
||||
webIdentityTrustPolicy(f.federatedARN, f.issuer, "system:serviceaccount:default:my-sa"))
|
||||
|
||||
token := f.signToken(f.defaultClaims())
|
||||
pathed := strings.Replace(aws.StringValue(role.Arn), ":role/", ":role/decoy/", 1)
|
||||
_, err := svc.AssumeRoleWithWebIdentity(&sts.AssumeRoleWithWebIdentityInput{
|
||||
RoleArn: aws.String(pathed),
|
||||
RoleSessionName: aws.String("pod-1"),
|
||||
WebIdentityToken: aws.String(token),
|
||||
})
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, awserrors.ErrorAccessDenied, err.Error())
|
||||
|
||||
// The stored ARN still works, so the denial is the path and nothing else.
|
||||
_, err = svc.AssumeRoleWithWebIdentity(&sts.AssumeRoleWithWebIdentityInput{
|
||||
RoleArn: role.Arn,
|
||||
RoleSessionName: aws.String("pod-1"),
|
||||
WebIdentityToken: aws.String(token),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -25,19 +25,28 @@ type RoleGetter interface {
|
||||
// discards any path in the supplied ARN, so comparing the stored ARN back is
|
||||
// what stops an invented path reaching a role the ARN does not name.
|
||||
func ResolveRoleByARN(svc RoleGetter, roleARN string) (string, *iam.Role, error) {
|
||||
accountID, roleName, err := auth.ParseRoleARN(roleARN)
|
||||
if err != nil {
|
||||
var role *iam.Role
|
||||
accountID, _, err := auth.ResolveRoleARN(roleARN, func(accountID, roleName string) (string, error) {
|
||||
out, err := svc.GetRole(accountID, &iam.GetRoleInput{RoleName: aws.String(roleName)})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if out == nil || out.Role == nil {
|
||||
return "", nil
|
||||
}
|
||||
role = out.Role
|
||||
return aws.StringValue(out.Role.Arn), nil
|
||||
})
|
||||
switch {
|
||||
case errors.Is(err, auth.ErrInvalidRoleARN):
|
||||
return "", nil, errors.New(awserrors.ErrorValidationError)
|
||||
}
|
||||
out, err := svc.GetRole(accountID, &iam.GetRoleInput{RoleName: aws.String(roleName)})
|
||||
if err != nil {
|
||||
case errors.Is(err, auth.ErrRoleARNMismatch):
|
||||
return "", nil, ErrRoleUnresolved
|
||||
case err != nil:
|
||||
if err.Error() == awserrors.ErrorIAMNoSuchEntity {
|
||||
return "", nil, ErrRoleUnresolved
|
||||
}
|
||||
return "", nil, err
|
||||
}
|
||||
if out == nil || out.Role == nil || aws.StringValue(out.Role.Arn) != roleARN {
|
||||
return "", nil, ErrRoleUnresolved
|
||||
}
|
||||
return accountID, out.Role, nil
|
||||
return accountID, role, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user