{"record":{"id":"ebf2438a31439044","repo":"kubernetes/kops","slug":"checking-if-bucket-was-public-w","errorCode":null,"errorMessage":"checking if bucket was public: %w","messagePattern":"checking if bucket was public: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/issuerdiscovery.go","lineNumber":98,"sourceCode":"\tvar publicFileACL *bool\n\n\tdiscoveryStorePath := b.Cluster.Spec.ServiceAccountIssuerDiscovery.DiscoveryStore\n\tdiscoveryStore, err := vfs.Context.BuildVfsPath(discoveryStorePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"building VFS path for %q: %w\", discoveryStorePath, err)\n\t}\n\n\tswitch discoveryStore := discoveryStore.(type) {\n\tcase *vfs.S3Path:\n\t\tdiscoveryStoreURL, err := discoveryStore.GetHTTPsUrl(b.Cluster.Spec.IsIPv6Only())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif discoveryStoreURL == fi.ValueOf(b.Cluster.Spec.KubeAPIServer.ServiceAccountIssuer) {\n\t\t\t// Using Amazon S3 static website hosting requires public access\n\t\t\tisPublic, err := discoveryStore.IsBucketPublic(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"checking if bucket was public: %w\", err)\n\t\t\t}\n\t\t\tif !isPublic {\n\t\t\t\tklog.Infof(\"serviceAccountIssuers bucket %q is not public; will use object ACL\", discoveryStore.Bucket())\n\t\t\t\tpublicFileACL = new(true)\n\t\t\t}\n\t\t} else {\n\t\t\tklog.Infof(\"using user managed serviceAccountIssuers\")\n\t\t}\n\tcase *vfs.GSPath:\n\t\tdiscoveryStoreURL, err := discoveryStore.GetHTTPsUrl()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif discoveryStoreURL == fi.ValueOf(b.Cluster.Spec.KubeAPIServer.ServiceAccountIssuer) {\n\t\t\t// Using Google Cloud Storage requires public access\n\t\t\tisPublic, err := discoveryStore.IsBucketPublic(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"checking if bucket was public: %w\", err)","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/issuerdiscovery.go#L80-L116","documentation":"When the discovery store is an S3 bucket and its HTTPS website URL equals kubeAPIServer.serviceAccountIssuer, kops relies on S3 static-website hosting and must know whether the bucket allows public reads. IsBucketPublic performs an S3 GetBucketPolicy/ACL check; any AWS API failure (permissions, connectivity) is wrapped in this error and fails the update.","triggerScenarios":"`kops update cluster` on AWS with discoveryStore pointing at an S3 bucket whose website URL matches the configured serviceAccountIssuer, while the S3 API call to inspect bucket policy/publicity fails (missing s3:GetBucketPolicy/s3:GetBucketAcl permission, blocked network, or bucket in another account).","commonSituations":"IAM user/role lacking GetBucketPolicy on the discovery bucket, bucket owned by a different AWS account, SCP denying public-access inspection (BlockPublicPolicy), or corporate proxy cutting off S3 endpoints.","solutions":["Grant the kops credentials s3:GetBucketPolicy, s3:GetBucketAcl and s3:GetBucketPublicAccessBlock on the discovery bucket.","Verify network access to the bucket's S3 endpoint (no proxy/firewall blocking) and that the bucket exists in the resolved region.","Confirm the bucket is in the account kops is operating against; mismatched accounts commonly cause AccessDenied here.","As a workaround, set kubeAPIServer.serviceAccountIssuer to a URL different from the bucket website URL so kops skips the publicity check (you then manage serving yourself)."],"exampleFix":"// before: IAM policy without bucket-policy read\n{\"Effect\":\"Allow\",\"Action\":[\"s3:PutObject\",\"s3:GetObject\"],\"Resource\":\"arn:aws:s3:::oidc-bucket/*\"}\n// after\n{\"Effect\":\"Allow\",\"Action\":[\"s3:PutObject\",\"s3:GetObject\",\"s3:GetBucketPolicy\",\"s3:GetBucketAcl\"],\"Resource\":[\"arn:aws:s3:::oidc-bucket\",\"arn:aws:s3:::oidc-bucket/*\"]}","handlingStrategy":"validation","validationCode":"// Pre-check bucket publicity and IAM permissions before running update:\nout, err := exec.Command(\"aws\", \"s3api\", \"get-bucket-policy-status\",\n    \"--bucket\", bucket).CombinedOutput()\nif err != nil {\n    return fmt.Errorf(\"cannot inspect bucket %s public status (check s3:GetBucketPolicy perms): %s: %v\", bucket, out, err)\n}","typeGuard":null,"tryCatchPattern":"err := runKopsUpdate(ctx)\nif err != nil && strings.Contains(err.Error(), \"checking if bucket was public\") {\n    // fall back: inspect bucket policy manually, or unset the issuer match to skip the check\n    log.Printf(\"S3 publicity check failed; verify IAM GetBucketPolicy perms: %v\", err)\n}","preventionTips":["Attach s3:GetBucketPolicy, s3:GetBucketAcl, s3:GetBucketPublicAccessBlock to kops' IAM identity.","Make the bucket public (or plan for object ACLs) before enabling issuer discovery.","Keep bucket and kops credentials in the same AWS account and region.","Use `aws s3api get-bucket-policy-status` as a dry-run sanity check."],"tags":["aws","s3","iam","permissions"],"backgroundTag":"aws-access-denied","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}