Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

feat: add support for IAM identity center permission set session duration #1514

Closed
wants to merge 11 commits into from
Closed
11 changes: 11 additions & 0 deletions avd_docs/aws/iamidentitycenter/AVD-AWS-0346/CloudFormation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

Define user session termination duration

```yaml---
Type: AWS::SSO::PermissionSet
Properties:
Description: "An example"
InstanceArn: String
Name: "Example"
SessionDuration: "PT2H"
```
14 changes: 14 additions & 0 deletions avd_docs/aws/iamidentitycenter/AVD-AWS-0346/Terraform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

Define user session termination duration

```hcl
resource "aws_ssoadmin_permission_set" "example" {
name = "Example"
description = "An example"
instance_arn = tolist(data.aws_ssoadmin_instances.example.arns)[0]
session_duration = "PT2H"
}
```

#### Remediation Links
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_permission_set#session_duration
11 changes: 11 additions & 0 deletions avd_docs/aws/iamidentitycenter/AVD-AWS-0346/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

Automatically terminate a user session after organization-defined conditions or trigger events requiring session disconnect.

### Impact
Extended user initiated sessions allow opportunity for misuse.

<!-- DO NOT CHANGE -->
{{ remediationActions }}

### Links
- https://docs.aws.amazon.com/singlesignon/latest/userguide/howtosessionduration.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package iamidentitycenter

import (
"github.com/aquasecurity/defsec/pkg/providers/aws/iamidentitycenter"
"github.com/aquasecurity/defsec/pkg/scanners/cloudformation/parser"

Check failure on line 5 in internal/adapters/cloudformation/aws/iamidentitycenter/iamidentitycenter.go

View workflow job for this annotation

GitHub Actions / building defsec (ubuntu-latest)

no required module provides package github.com/aquasecurity/defsec/pkg/scanners/cloudformation/parser; to add it:
)

// Adapt ...
func Adapt(cfFile parser.FileContext) iamidentitycenter.IAMIdentityCenter {
return iamidentitycenter.IAMIdentityCenter{
PermissionSets: getPermissionSets(cfFile),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package iamidentitycenter

import (
"github.com/aquasecurity/defsec/pkg/providers/aws/iamidentitycenter"
"github.com/aquasecurity/defsec/pkg/scanners/cloudformation/parser"
)

func getPermissionSets(ctx parser.FileContext) (permissionsets []iamidentitycenter.PermissionSet) {
for _, r := range ctx.GetResourcesByType("AWS::SSO::PermissionSet") {

permissionset := iamidentitycenter.PermissionSet{
Metadata: r.Metadata(),
SessionDuration: r.GetStringProperty("SessionDuration"),
}
permissionsets = append(permissionsets, permissionset)
}
return permissionsets
}
35 changes: 35 additions & 0 deletions internal/adapters/terraform/aws/iamidentitycenter/adapt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package iamidentitycenter

import (
"github.com/aquasecurity/defsec/pkg/providers/aws/iamidentitycenter"
"github.com/aquasecurity/defsec/pkg/terraform"
defsecTypes "github.com/aquasecurity/defsec/pkg/types"
)

func Adapt(modules terraform.Modules) iamidentitycenter.IAMIdentityCenter {
return iamidentitycenter.IAMIdentityCenter{
PermissionSets: adaptPermissionSets(modules),
}
}

func adaptPermissionSets(modules terraform.Modules) []iamidentitycenter.PermissionSet {
var permissionSets []iamidentitycenter.PermissionSet
for _, module := range modules {
for _, resource := range module.GetResourcesByType("aws_ssoadmin_permission_set") {
permissionSets = append(permissionSets, adaptPermissionSet(resource))
}
}
return permissionSets
}

func adaptPermissionSet(resource *terraform.Block) iamidentitycenter.PermissionSet {
permissionSet := iamidentitycenter.PermissionSet{
Metadata: resource.GetMetadata(),
SessionDuration: defsecTypes.StringDefault("", resource.GetMetadata()),
}

sessionDuration := resource.GetAttribute("session_duration")
permissionSet.SessionDuration = sessionDuration.AsStringValueOrDefault("", resource)

return permissionSet
}
73 changes: 73 additions & 0 deletions internal/adapters/terraform/aws/iamidentitycenter/adapt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package iamidentitycenter

import (
"testing"

defsecTypes "github.com/aquasecurity/defsec/pkg/types"

"github.com/aquasecurity/defsec/pkg/providers/aws/iamidentitycenter"

"github.com/aquasecurity/defsec/internal/adapters/terraform/tftestutil"

"github.com/aquasecurity/defsec/test/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_adaptPermissionSet(t *testing.T) {
tests := []struct {
name string
terraform string
expected iamidentitycenter.PermissionSet
}{
{
name: "configured",
terraform: `
resource "aws_ssoadmin_permission_set" "example" {
session_duration = "PT2H"
}
`,
expected: iamidentitycenter.PermissionSet{
Metadata: defsecTypes.NewTestMetadata(),
SessionDuration: defsecTypes.String("PT2H", defsecTypes.NewTestMetadata()),
},
},
{
name: "defaults",
terraform: `
resource "aws_ssoadmin_permission_set" "example" {
}
`,
expected: iamidentitycenter.PermissionSet{
Metadata: defsecTypes.NewTestMetadata(),
SessionDuration: defsecTypes.String("", defsecTypes.NewTestMetadata()),
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
modules := tftestutil.CreateModulesFromSource(t, test.terraform, ".tf")
adapted := adaptPermissionSet(modules.GetBlocks()[0])
testutil.AssertDefsecEqual(t, test.expected, adapted)
})
}
}

func TestLines(t *testing.T) {
src := `
resource "aws_ssoadmin_permission_set" "example" {
session_duration = "PT2H"
}`
modules := tftestutil.CreateModulesFromSource(t, src, ".tf")
adapted := Adapt(modules)

require.Len(t, adapted.PermissionSets, 1)
permissionSet := adapted.PermissionSets[0]

assert.Equal(t, 2, permissionSet.Metadata.Range().GetStartLine())
assert.Equal(t, 4, permissionSet.Metadata.Range().GetEndLine())

assert.Equal(t, 3, permissionSet.SessionDuration.GetMetadata().Range().GetStartLine())
assert.Equal(t, 3, permissionSet.SessionDuration.GetMetadata().Range().GetEndLine())
}
72 changes: 37 additions & 35 deletions pkg/providers/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/aquasecurity/defsec/pkg/providers/aws/elb"
"github.com/aquasecurity/defsec/pkg/providers/aws/emr"
"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/providers/aws/iamidentitycenter"
"github.com/aquasecurity/defsec/pkg/providers/aws/kinesis"
"github.com/aquasecurity/defsec/pkg/providers/aws/kms"
"github.com/aquasecurity/defsec/pkg/providers/aws/lambda"
Expand All @@ -38,41 +39,42 @@ import (
)

type AWS struct {
Meta Meta
AccessAnalyzer accessanalyzer.AccessAnalyzer
APIGateway apigateway.APIGateway
Athena athena.Athena
Cloudfront cloudfront.Cloudfront
CloudTrail cloudtrail.CloudTrail
CloudWatch cloudwatch.CloudWatch
CodeBuild codebuild.CodeBuild
Config config.Config
DocumentDB documentdb.DocumentDB
DynamoDB dynamodb.DynamoDB
EC2 ec2.EC2
ECR ecr.ECR
ECS ecs.ECS
EFS efs.EFS
EKS eks.EKS
ElastiCache elasticache.ElastiCache
Elasticsearch elasticsearch.Elasticsearch
ELB elb.ELB
EMR emr.EMR
IAM iam.IAM
Kinesis kinesis.Kinesis
KMS kms.KMS
Lambda lambda.Lambda
MQ mq.MQ
MSK msk.MSK
Neptune neptune.Neptune
RDS rds.RDS
Redshift redshift.Redshift
SAM sam.SAM
S3 s3.S3
SNS sns.SNS
SQS sqs.SQS
SSM ssm.SSM
WorkSpaces workspaces.WorkSpaces
Meta Meta
AccessAnalyzer accessanalyzer.AccessAnalyzer
APIGateway apigateway.APIGateway
Athena athena.Athena
Cloudfront cloudfront.Cloudfront
CloudTrail cloudtrail.CloudTrail
CloudWatch cloudwatch.CloudWatch
CodeBuild codebuild.CodeBuild
Config config.Config
DocumentDB documentdb.DocumentDB
DynamoDB dynamodb.DynamoDB
EC2 ec2.EC2
ECR ecr.ECR
ECS ecs.ECS
EFS efs.EFS
EKS eks.EKS
ElastiCache elasticache.ElastiCache
Elasticsearch elasticsearch.Elasticsearch
ELB elb.ELB
EMR emr.EMR
IAM iam.IAM
IAMIdentityCenter iamidentitycenter.IAMIdentityCenter
Kinesis kinesis.Kinesis
KMS kms.KMS
Lambda lambda.Lambda
MQ mq.MQ
MSK msk.MSK
Neptune neptune.Neptune
RDS rds.RDS
Redshift redshift.Redshift
SAM sam.SAM
S3 s3.S3
SNS sns.SNS
SQS sqs.SQS
SSM ssm.SSM
WorkSpaces workspaces.WorkSpaces
}

type Meta struct {
Expand Down
14 changes: 14 additions & 0 deletions pkg/providers/aws/iamidentitycenter/iamidentitycenter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package iamidentitycenter

import (
defsecTypes "github.com/aquasecurity/defsec/pkg/types"
)

type IAMIdentityCenter struct {
PermissionSets []PermissionSet
}

type PermissionSet struct {
Metadata defsecTypes.Metadata
SessionDuration defsecTypes.StringValue
}
25 changes: 25 additions & 0 deletions pkg/rego/schemas/cloud.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.IAM"
},
"iamidentitycenter": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iamidentitycenter.IAMIdentityCenter"
},
"kinesis": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.kinesis.Kinesis"
Expand Down Expand Up @@ -2359,6 +2363,27 @@
}
}
},
"github.com.aquasecurity.defsec.pkg.providers.aws.iamidentitycenter.IAMIdentityCenter": {
"type": "object",
"properties": {
"permissionsets": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iamidentitycenter.PermissionSet"
}
}
}
},
"github.com.aquasecurity.defsec.pkg.providers.aws.iamidentitycenter.PermissionSet": {
"type": "object",
"properties": {
"sessionduration": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue"
}
}
},
"github.com.aquasecurity.defsec.pkg.providers.aws.kinesis.Encryption": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package iamidentitycenter

var cloudFormationSessionDurationGoodExamples = []string{
`---
Type: AWS::SSO::PermissionSet
Properties:
Description: "An example"
InstanceArn: String
Name: "Example"
SessionDuration: "PT2H"
`,
}

var cloudFormationSessionDurationBadExamples = []string{
`---
Type: AWS::SSO::PermissionSet
Properties:
Description: "An example"
InstanceArn: String
Name: "Example"
SessionDuration: ""
`,
}

var cloudFormationSessionDurationLinks = []string{
`https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sso-permissionset.html#cfn-sso-permissionset-sessionduration`,
}

var cloudFormationSessionDurationRemediationMarkdown = ``
Loading
Loading