GithubHelp home page GithubHelp logo

jameswoolfenden / pike Goto Github PK

View Code? Open in Web Editor NEW
502.0 6.0 21.0 3.57 MB

Pike is a tool for determining the permissions or policy required for IAC code

License: Apache License 2.0

Go 55.74% HCL 43.18% Makefile 0.46% JavaScript 0.29% Shell 0.13% Dockerfile 0.06% PowerShell 0.13% Python 0.01%
iac policy terraform bridgecrew security aws gcp

pike's Introduction

Pike

alt text

Maintenance Build Status Latest Release GitHub tag (latest SemVer) Terraform Version pre-commit checkov Github All Releases codecov OpenSSF Best Practices

Pike is a tool, to determine the minimum permissions required to run a TF/IAC run:

Pike currently supports Terraform and supports multiple providers (AWS, GCP, AZURE), Azure is the newest with AWS having the most supported resources https://github.com/JamesWoolfenden/pike/tree/master/src/mapping. Feel free to submit PR or Issue if you find an issue or even better add new resources, and then I'll take a look at merging it ASAP.

CAVEAT The outputs of this tool are your first step, if you have AWS, you can now generate resources partially, there are no conditions and even partial resources are wildcarded (for now). (for AWS) best practice would go further (and I am working on it as well), you will need to modify these permissions to the minimum required in your enviornment by adding these restrictions, you can also deploy using short lived credentials (using this tool or Vault) (in AWS so far), generating short-lived credentials for your build and then remotely (REMOTE) supply and invoke your builds (INVOKE).

Ideally I would like to do this for you, but these policies are currently determined statically (QUICKER), and unrecorded intentions can be impossible to infer.

Table of Contents

Install

Download the latest binary here:

https://github.com/JamesWoolfenden/pike/releases

Install from code:

  • Clone repo
  • Run go install

Install remotely:

go install  github.com/jameswoolfenden/pike@latest

MacOS

brew tap jameswoolfenden/homebrew-tap
brew install jameswoolfenden/tap/pike

Windows

I'm now using Scoop to distribute releases, it's much quicker to update and easier to manage than previous methods, you can install scoop from https://scoop.sh/.

Add my scoop bucket:

scoop bucket add iac https://github.com/JamesWoolfenden/scoop.git

Then you can install a tool:

scoop install pike

Docker

docker pull jameswoolfenden/pike
docker run --tty --volume /local/path/to/tf:/tf jameswoolfenden/pike scan -d /tf

https://hub.docker.com/repository/docker/jameswoolfenden/pike

Usage

Scan

To scan a directory containing Terraform files:

./pike scan -d .\terraform\
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "ec2:MonitorInstances",
            "ec2:UnmonitorInstances",
            "ec2:DescribeInstances",
            "ec2:DescribeTags",
            "ec2:DescribeInstanceAttribute",
            "ec2:DescribeVolumes",
            "ec2:DescribeInstanceTypes",
            "ec2:RunInstances",
            "ec2:DescribeInstanceCreditSpecifications",
            "ec2:StopInstances",
            "ec2:StartInstances",
            "ec2:ModifyInstanceAttribute",
            "ec2:TerminateInstances",
            "ec2:AuthorizeSecurityGroupIngress",
            "ec2:AuthorizeSecurityGroupEgress",
            "ec2:CreateSecurityGroup",
            "ec2:DescribeSecurityGroups",
            "ec2:DescribeAccountAttributes",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DeleteSecurityGroup",
            "ec2:RevokeSecurityGroupEgress"
        ],
        "Resource": "*"
    }
}

You can also generate the policy as Terraform instead:

$pike scan -o terraform -d ../modules/aws/terraform-aws-activemq
resource "aws_iam_policy" "terraformXVlBzgba" {
  name        = "terraformXVlBzgba"
  path        = "/"
  description = "Add Description"

  policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:AuthorizeSecurityGroupEgress",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:CreateNetworkInterface",
                "ec2:CreateNetworkInterfacePermission",
                "ec2:CreateSecurityGroup",
                "ec2:CreateTags",
                "ec2:DeleteNetworkInterface",
                "ec2:DeleteNetworkInterfacePermission",
                "ec2:DeleteSecurityGroup",
                "ec2:DeleteTags",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "ec2:DetachNetworkInterface",
                "ec2:RevokeSecurityGroupEgress",
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "kms:CreateKey",
                "kms:DescribeKey",
                "kms:EnableKeyRotation",
                "kms:GetKeyPolicy",
                "kms:GetKeyRotationStatus",
                "kms:ListResourceTags",
                "kms:ScheduleKeyDeletion",
                "kms:TagResource",
                "kms:UntagResource"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "mq:CreateBroker",
                "mq:CreateConfiguration",
                "mq:CreateTags",
                "mq:CreateUser",
                "mq:DeleteBroker",
                "mq:DeleteTags",
                "mq:DeleteUser",
                "mq:DescribeBroker",
                "mq:DescribeConfiguration",
                "mq:DescribeConfigurationRevision",
                "mq:DescribeUser",
                "mq:RebootBroker",
                "mq:UpdateBroker",
                "mq:UpdateConfiguration",
                "mq:UpdateUser"
            ],
            "Resource": "*"
        }
    ]
})
}

And I am working on further enhancements to policy generation, if you have AWS auth installed:

e:\pike scan -d . -i -e
9:13AM DBG terraform init at E:\Code\modules\aws\terraform-aws-activemq
9:13AM DBG downloaded ip
resource "aws_iam_policy" "terraform_pike" {
  name_prefix = "terraform_pike"
  path        = "/"
  description = "Pike Autogenerated policy from IAC"

  policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:AuthorizeSecurityGroupEgress",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:CreateNetworkInterface",
                "ec2:CreateNetworkInterfacePermission",
                "ec2:CreateSecurityGroup",
                "ec2:CreateTags",
                "ec2:DeleteNetworkInterface",
                "ec2:DeleteNetworkInterfacePermission",
                "ec2:DeleteSecurityGroup",
                "ec2:DeleteTags",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "ec2:DetachNetworkInterface",
                "ec2:RevokeSecurityGroupEgress",
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": [
                "arn:aws:ec2:eu-west-2:680235478471:*"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "kms:CreateGrant"
            ],
            "Resource": [
                "arn:aws:kms:eu-west-2:680235478471:*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "mq:CreateBroker",
                "mq:CreateConfiguration",
                "mq:CreateTags",
                "mq:CreateUser",
                "mq:DeleteBroker",
                "mq:DeleteTags",
                "mq:DeleteUser",
                "mq:DescribeBroker",
                "mq:DescribeConfiguration",
                "mq:DescribeConfigurationRevision",
                "mq:DescribeUser",
                "mq:RebootBroker",
                "mq:UpdateBroker",
                "mq:UpdateConfiguration",
                "mq:UpdateUser"
            ],
            "Resource": [
                "arn:aws:mq:eu-west-2:680235478471:*"
            ]
        }
    ]
})
}

I'm not finished with this yet as I am also working on bringing in resource names into the policies.

Output

If you select the -w flag, pike will write out the role/policy required to build your project into the .pike folder:

$pike scan -w -i -d .
2022/09/17 13:50:51 terraform init at .
2022/09/17 13:50:51 downloaded ip

The .pike folder will contain:

aws_iam_role.terraform_pike.tf
pike.generated_policy.tf

Which you can deploy using terraform to create the role/policy to build your IAC project.

Make

You can now deploy the policy you need directly (AWS only so far):

$pike make -d ../modules/aws/terraform-aws-apigateway/

2022/09/18 08:53:41 terraform init at ..\modules\aws\terraform-aws-apigateway\
2022/09/18 08:53:41 modules not found at ..\modules\aws\terraform-aws-apigateway\
2022/09/18 08:53:49 aws role create/updated arn:aws:iam::680235478471:role/terraform_pike_20220918071439382800000002
 arn:aws:iam::680235478471:role/terraform_pike_20220918071439382800000002

This new verb returns the ARN of the role created, and you can find the Terraform used in your .pike folder.

Invoke

Invoke is currently for triggering GitHub actions, if supplied with the workflow (defaults to main.yaml), repository and branch (defaults to main) flags, it will trigger the dispatch event.

You'll need to include the dispatch event in your workflow:

on:
  workflow_dispatch:
  push:
    branches:
      - master

To authenticate the GitHub Api you will need to set you GitHub Personal Access Token as the environment variable GITHUB_TOKEN

To Invoke a workflow it is then:

pike invoke -workflow master.yml -branch master -repository JamesWoolfenden/terraform-aws-s3

I created Invoke to be used in tandem with the new remote command which supplies temporary credentials to a workflow.

**Note The gitHub API is rate limited usually 5000 calls per hour.

pike make -d ./module/aws/terraform-aws-s3/example/examplea

Apply

Apply is an extension to make and will apply the policy and role and use that role to create your infrastructure:

pike apply -d ./module/aws/terraform-aws-s3/example/examplea -region eu-west-2

It is intended for testing and developing the permissions for Pike itself

Remote

Remote uses the core code of make and apply, to write temporary AWS credentials(only so far) into your workflow.

pike remote -d ./module/aws/terraform-aws-s3/example/examplea -region eu-west-2 -repository terraform-aws-s3

Readme

Pike can now be used to update a projects README.md file:

./pike readme -o terraform -d ..\modules\aws\terraform-aws-activemq\

This looks in the readme for the deliminators:

<!-- BEGINNING OF PRE-COMMIT-PIKE DOCS HOOK -->
<!-- END OF PRE-COMMIT-PIKE DOCS HOOK -->

and replaces is either with json or Terraform like so:

This is the policy required to build this project:

The Policy required is

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "mq:CreateTags",
            "mq:DeleteTags",
            "ec2:DescribeInternetGateways",
            "ec2:DescribeAccountAttributes",
            "ec2:DescribeVpcs",
            "ec2:DescribeSubnets",
            "ec2:DescribeSecurityGroups",
            "ec2:CreateNetworkInterface",
            "ec2:CreateNetworkInterfacePermission",
            "ec2:DeleteNetworkInterfacePermission",
            "ec2:DetachNetworkInterface",
            "ec2:DeleteNetworkInterface",
            "mq:CreateBroker",
            "mq:DescribeBroker",
            "mq:DescribeUser",
            "mq:UpdateBroker",
            "mq:DeleteBroker",
            "mq:CreateConfiguration",
            "mq:UpdateConfiguration",
            "mq:DescribeConfiguration",
            "mq:DescribeConfigurationRevision",
            "mq:RebootBroker",
            "ec2:CreateTags",
            "ec2:DeleteTags",
            "ec2:CreateSecurityGroup",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DeleteSecurityGroup",
            "ec2:RevokeSecurityGroupEgress",
            "kms:TagResource",
            "kms:UntagResource",
            "kms:EnableKeyRotation",
            "kms:CreateKey",
            "kms:DescribeKey",
            "kms:GetKeyPolicy",
            "kms:GetKeyRotationStatus",
            "kms:ListResourceTags",
            "kms:ScheduleKeyDeletion"
        ],
        "Resource": "*"
    }
}

You can see an example here https://github.com/jamesWoolfenden/terraform-aws-activemq#policy.

Compare

Want to check your deployed IAM policy against your IAC requirement?

$./pike compare -d ../modules/aws/terraform-aws-appsync -a arn:aws:iam::680235478471:policy/basic

IAM Policy arn:aws:iam::680235478471:policy/basic versus Local ../modules/aws/terraform-aws-appsync
 {
   "Statement": [
     0: {
       "Action": [
-        0: "kinesisvideo:CreateStream"
+        0: "firehose:CreateDeliveryStream"
+        0: "firehose:CreateDeliveryStream"
+        1: "firehose:DeleteDeliveryStream"
+        2: "firehose:DescribeDeliveryStream"
+        3: "firehose:ListTagsForDeliveryStream"
+        4: "iam:AttachRolePolicy"
+        5: "iam:CreateRole"
+        6: "iam:DeleteRole"
+        7: "iam:DetachRolePolicy"
+        8: "iam:GetRole"
+        9: "iam:ListAttachedRolePolicies"
+        10: "iam:ListInstanceProfilesForRole"
+        11: "iam:ListRolePolicies"
+        12: "iam:PassRole"
+        13: "iam:TagRole"
+        14: "kms:CreateKey"
+        15: "kms:DescribeKey"
+        16: "kms:EnableKeyRotation"
+        17: "kms:GetKeyPolicy"
+        18: "kms:GetKeyRotationStatus"
+        19: "kms:ListResourceTags"
+        20: "kms:ScheduleKeyDeletion"
+        21: "logs:AssociateKmsKey"
+        22: "logs:CreateLogGroup"
+        23: "logs:DeleteLogGroup"
+        24: "logs:DeleteRetentionPolicy"
+        25: "logs:DescribeLogGroups"
+        26: "logs:DisassociateKmsKey"
+        27: "logs:ListTagsLogGroup"
+        28: "logs:PutRetentionPolicy"
+        29: "s3:CreateBucket"
+        30: "s3:DeleteBucket"
+        31: "s3:GetAccelerateConfiguration"
+        32: "s3:GetBucketAcl"
+        33: "s3:GetBucketCORS"
+        34: "s3:GetBucketLogging"
+        35: "s3:GetBucketObjectLockConfiguration"
+        36: "s3:GetBucketPolicy"
+        37: "s3:GetBucketPublicAccessBlock"
+        38: "s3:GetBucketRequestPayment"
+        39: "s3:GetBucketTagging"
+        40: "s3:GetBucketVersioning"
+        41: "s3:GetBucketWebsite"
+        42: "s3:GetEncryptionConfiguration"
+        43: "s3:GetLifecycleConfiguration"
+        44: "s3:GetObject"
+        45: "s3:GetObjectAcl"
+        46: "s3:GetReplicationConfiguration"
+        47: "s3:ListAllMyBuckets"
+        48: "s3:ListBucket"
+        49: "s3:PutBucketAcl"
+        50: "s3:PutBucketPublicAccessBlock"
+        51: "s3:PutEncryptionConfiguration"
+        52: "wafv2:CreateWebACL"
+        53: "wafv2:DeleteWebACL"
+        54: "wafv2:GetWebACL"
       ],
       "Effect": "Allow",
       "Resource": "*",
-      "Sid": ""
+      "Sid": "VisualEditor0"
     }
   ],
   "Version": "2012-10-17"
 }

Pull

Pull adds the ability to work with Git repositories (thanks to go-git), to output the required permissions in json or Terraform:

./pike  pull
NAME:
   pike pull - Clones remote repo and scans it using pike

USAGE:
   pike pull [command options] [arguments...]

OPTIONS:
   --directory value, -d value        Directory to scan (defaults to .) (default: ".")
   --destination value, --dest value  Where to clone repository (default: ".destination")
   --output json, -o json             Policy Output types e.g. json terraform (default: "terraform") [%OUTPUT%]
   --repository value, -r value       Repository url
   --init, -i                         Run Terraform init to download modules (default: false)
   --write, -w                        Write the policy output to a file at .pike (default: false)
   --help, -h                         show help

Like so:

$ ./pike.exe pull -r https://github.com/JamesWoolfenden/terraform-aws-codebuild -i -d .
10:31PM INF .destination was not empty, removing
10:31PM INF git clone https://github.com/JamesWoolfenden/terraform-aws-codebuild .destination --recursive
10:31PM DBG terraform init at E:\Code\pike\.destination
10:31PM DBG modules not found at .destination
resource "aws_iam_policy" "terraform_pike" {
  name_prefix = "terraform_pike"
  path        = "/"
  description = "Pike Autogenerated policy from IAC"

  policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "codebuild:BatchGetProjects",
                "codebuild:CreateProject",
                "codebuild:DeleteProject",
                "codebuild:UpdateProject"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListTagsForResource",
                "events:ListTargetsByRule",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:CreatePolicy",
                "iam:CreateRole",
                "iam:DeletePolicy",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:DetachRolePolicy",
                "iam:GetPolicy",
                "iam:GetPolicyVersion",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:ListAttachedRolePolicies",
                "iam:ListInstanceProfilesForRole",
                "iam:ListPolicyVersions",
                "iam:ListRolePolicies",
                "iam:PassRole",
                "iam:PutRolePolicy",
                "iam:TagRole"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "VisualEditor4",
            "Effect": "Allow",
            "Action": [
                "s3:CreateBucket",
                "s3:DeleteBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketAcl",
                "s3:GetBucketCORS",
                "s3:GetBucketLogging",
                "s3:GetBucketObjectLockConfiguration",
                "s3:GetBucketPolicy",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketRequestPayment",
                "s3:GetBucketTagging",
                "s3:GetBucketVersioning",
                "s3:GetBucketWebsite",
                "s3:GetEncryptionConfiguration",
                "s3:GetLifecycleConfiguration",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:GetReplicationConfiguration",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:PutBucketAcl",
                "s3:PutBucketLogging",
                "s3:PutBucketPublicAccessBlock",
                "s3:PutBucketVersioning",
                "s3:PutEncryptionConfiguration",
                "s3:PutLifecycleConfiguration"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "VisualEditor5",
            "Effect": "Allow",
            "Action": [
                "ssm:AddTagsToResource",
                "ssm:DeleteParameter",
                "ssm:DescribeParameters",
                "ssm:GetParameter",
                "ssm:GetParameters",
                "ssm:ListTagsForResource",
                "ssm:PutParameter"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
})
}

Help

./pike -h
NAME:
   pike - Generate IAM policy from your IAC code

USAGE:
   pike [global options] command [command options] [arguments...]

VERSION:
   v0.2.107

AUTHOR:
   James Woolfenden <[email protected]>

COMMANDS:
   apply, a    Create a policy and use it to instantiate the IAC
   compare, c  policy comparison of deployed versus IAC
   invoke, i   Triggers a gitHub action specified with the workflow flag
   make, m     make the policy/role required for this IAC to deploy
   parse, p    Triggers a gitHub action specified with the workflow flag
   pull, p     Clones remote repo and scans it using pike
   readme, r   Looks in dir for a README.md and updates it with the Policy required to build the code
   remote, m   Create/Update the Policy and set credentials/secret for Github Action
   scan, s     scan a directory for IAM code
   version, v  Outputs the application version
   watch, w    Waits for policy update
   help, h     Shows a list of commands or help for one command


GLOBAL OPTIONS:
   --help, -h     show help (default: false)
   --version, -v  print the version (default: false)

Building

go build

or

Make build

Extending

Determine and Create IAM mapping file ("./src/mapping"), working out the permissions required for your resource: e.g. aws_security_group.json

[
  {
    "apply": [
      "ec2:CreateSecurityGroup",
      "ec2:DescribeSecurityGroups",
      "ec2:DescribeAccountAttributes",
      "ec2:DescribeNetworkInterfaces",
      "ec2:DeleteSecurityGroup",
      "ec2:RevokeSecurityGroupEgress"
    ],
    "attributes": {
      "ingress": [
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:AuthorizeSecurityGroupEgress"
      ],
      "tags": [
        "ec2:CreateTags",
        "ec2:DeleteTags"
      ]
    },
    "destroy": [
      "ec2:DeleteSecurityGroup"
    ],
    "modify": [],
    "plan": []
  }
]

How

Datasources are the easiest to start with, I have a script (resource.ps1 - add pwsh with brew install --cask powershell) that creates a blank mapping file and tf resource, but you've seen the example json file - make one without any entries. You also need to create a minimal resource/datasource, that you are trying to figure out the permissions for, and place it in the correct dir e.g../terraform/aws, I have a script for making a profile for the profile in the role directory. You can then tf using the empty role against the resource/datasource with no permissions. The debug output from the tf run will help you figure out the permissions you need to add to your basic role. You then update your "basic" role.

Issues? The providers don't always tell you want you need to add, you will need to check the IAM docs and the online IAM policymakers. Not all resource are as easy as others, anything that make/scripts CF internally. Some roles require Passrole and CreateLinkedRole but won't say so. Trail and error

What about "attributes" ?

Some cloud providers require extra permissions depending on the attributes you add, this is how this is handled. Build out your tf resources to cover all reasonable scenarios.

Eventual consistency

Some cloud providers follow this model which means your test IAM role will take time after you change it to be changed, how long? This seems to vary on time of day and the resource. Whilst other providers like Azure just take a long time for the TF to change.

Add Import mapping file

Update files.go with:

//go:embed aws_security_group.json
var securityGroup []byte

Add to provider Scan

Once you have added the json import above you just need to update the lookup table, so we can read it and get the permissions:

func GetAWSResourcePermissions(result template) []interface{} {
    TFLookup := map[string]interface{}{
        "aws_s3_bucket":            awsS3Bucket,
        "aws_s3_bucket_acl":        awsS3BucketACL,
+         "aws_security_group":       awsSecurityGroup,

Also add an example Terraform file into the folder terraform//backups this helps test that all your new code is picked up pby pike.

Related Tools

https://github.com/iann0036/iamlive

Star History

Star History Chart

pike's People

Contributors

dependabot[bot] avatar gruebel avatar jameswoolfenden avatar kartikp10 avatar seifrajhi avatar sjiveson avatar tomaszkrzyzanowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pike's Issues

Create pre-commit hook to generate policy file

Diff against existing policy

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

more resources

aws_acmpca_certificate not implemented
aws_acmpca_certificate_authority_certificate not implemented

detect s3 backend config

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Add retries to policy use after iam creation

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Nothing Major, but version is not shown with v or version

Loving the tool, brilliant thanks!

Describe the bug
Just one minor thing, on Linux or Windows, if I run pike v, or pike version, the output is blank...

To Reproduce
Steps to reproduce the behavior:
run pike v, or pike version in linux or windows

create test process for new resources/datasource

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

generate gcp role with make

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Submodules of downloaded modules are not found

Describe the bug
When using a complex root module, then the path to sub modules are not found within the downloaded modules below .terraform.

To Reproduce
Steps to reproduce the behavior:

docker run --tty --volume pwd:/tf jameswoolfenden/pike scan -d /tf

  1. Use a module with "submodules" directories, example:
    ├── modules
    │   ├── container-definition
    │   │   ├── main.tf
    │   │   ├── MODULE.md
    │   │   ├── outputs.tf
    │   │   ├── README.md
    │   │   ├── variables.tf
    │   │   └── versions.tf
    │   ├── ecs-cluster
    │   │   ├── main.tf
    │   │   ├── MODULE.md
    │   │   ├── outputs.tf
    │   │   ├── README.md
    │   │   ├── variables.tf
    │   │   └── versions.tf
    │   ├── ecs-service
    │   │   ├── main.tf
    │   │   ├── MODULE.md
    │   │   ├── outputs.tf
    │   │   ├── README.md
    │   │   ├── variables.tf
    │   │   └── versions.tf
    │   └── ecs-task
    │   ├── main.tf
    │   ├── MODULE.md
    │   ├── outputs.tf
    │   ├── README.md
    │   ├── templates
    │   │   └── ecs_task_execution_role.json
    │   ├── variables.tf
    │   └── versions.tf
    ├── main.tf
    ├── outputs.tf
    ├── README.md
    ├── variables.tf
    └── versions.tf

  2. run pike scan

  3. The debug output will state:
    7:05PM DBG getTF folder /tf/modules/ecs-task can't be found
    7:05PM DBG getTF folder /tf/modules/ecs-service can't be found
    7:05PM DBG getTF folder /tf/modules/ecs-cluster can't be found
    7:05PM DBG getTF folder /tf/modules/ecs-task can't be found
    7:05PM DBG getTF folder /tf/modules/ecs-service can't be found

Expected behavior
pike should find the submodules within the downloaded module below .terraform/modules/container.ecs_cluster:
└── modules
├── container-definition
├── ecs-cluster
├── ecs-service
└── ecs-task
└── templates

Desktop (please complete the following information):

  • OS: Linux
  • Docker Version: jameswoolfenden/pike:latest

Additional context

When i link the submodule directories to the modules directory, pike will add needed IAM permissions to the policy:

eg ln-s .terraform/modules/container.ecs_cluster/modules/ecs-service modules/ecs-service within the root of the terraform root module.

Hope this is easy to fix,
Jörg

add unit tests

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

support for azure

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

add azurerm_kubernetes_cluster

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

target against planned output files

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Auto-Update?

Hi @JamesWoolfenden

I noted you've been releasing a lot lately, so I wondered if it might be an idea to have an update option in pike where you can update to the latest release using the tool?

For Windows/Linux I wrote a couple of scripts that I've scheduled to check daily & pull the latest version, but might be an idea?

Scripts for info, or if you can't be bothered to do an auto-updater, maybe you could include these somewhere if someone else might want to use? (I'm don't have a Mac so can't write something for that).

Windows/Powershell: (uncommenting the last line if you want options to be different)

function GetLatestPike {
  param (
    [parameter(Mandatory = $false)]$Match = "windows_amd64",
    [parameter(Mandatory = $false)]$Root = "$env:userprofile\Downloads",
    [parameter(Mandatory = $false)]$Target = "C:\Windows"
  )
  $ProgressPreference = "SilentlyContinue"
  [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
  
  $GithubUrl = "https://api.github.com/repos/JamesWoolfenden/pike/releases/latest"
  $Response = Invoke-WebRequest -Uri $GithubUrl -MaximumRedirection 0 -ErrorAction SilentlyContinue
  $LatestRelease = $Response.Content | ConvertFrom-Json
  $LatestUrl = $LatestRelease.assets | Where-Object { $_.browser_download_url -like "*$Match*" }
  $LatestName = $LatestUrl.name
  $zipDownloadUrl = $LatestUrl.browser_download_url
  
  $DLFol = Join-Path -Path $Root -ChildPath $LatestName.Replace(".zip", "")
  
  if (-not (Test-Path -Path $DLFol -PathType Container)) {
    New-Item -Path $DLFol -ItemType Directory | out-null
    Write-Host "Folder: $DLFol created.." -Fore Cyan
  } else { 
    Write-Host "The latest version is already present...  exiting.." -Fore Yellow
    break
  }
  
  $zipFilePath = Join-Path -Path $DLFol -ChildPath $LatestName
  Invoke-WebRequest -Uri $zipDownloadUrl -OutFile $zipFilePath
  Expand-Archive -Path $zipFilePath -DestinationPath $DLFol -Force
  Remove-Item -Path $zipFilePath
  Copy-Item -Path "$DLFol\pike.exe" -Destination "$Target\pike.exe" -Force
  
  Write-Host "Latest pike installed from $DLFol.." -Fore Green
}

GetLatestPike #-Match windows_amd64 -Root C:\tmp -Target c:\Windows

Linux/Bash: (uncommenting the last line if you want options to be different)

#!/bin/bash

get_latest_pike() {
    local Match="${1:-linux_amd64}"
    local Root="${2:-/home/alex/Downloads}"
    local Target="${3:-/usr/local/bin}"

    local GithubUrl="https://api.github.com/repos/JamesWoolfenden/pike/releases/latest"
    local LatestRelease
    LatestRelease=$(curl -s "$GithubUrl")

    local LatestUrl
    LatestUrl=$(echo "$LatestRelease" | jq -r '.assets[] | select(.browser_download_url | contains("'"$Match"'")) | .browser_download_url')

    if [ -z "$LatestUrl" ]; then
        echo "No matching asset found for $Match"
        exit 1
    fi

    local LatestName
    LatestName=$(basename "$LatestUrl")
    local ext=".tar.gz"
    local zipDownloadUrl="$LatestUrl"
    local DLFol="$Root/${LatestName%$ext}"

    if [ ! -d "$DLFol" ]; then
        mkdir -p "$DLFol"
        echo "Folder: $DLFol created.."
    else
        echo "The latest version is already present... exiting.."
        exit 0
    fi

    local zipFilePath="$DLFol/$LatestName"
    curl -L -o "$zipFilePath" "$zipDownloadUrl"
    tar -xzf "$zipFilePath" -C "$DLFol"
    rm -f "$zipFilePath"
    cp "$DLFol/pike" "$Target/pike"
    echo "Latest pike installed from $DLFol.."
}

get_latest_pike #"other_match" "/path/to/root" "/path/to/target"

Cheers

FEATURE - Run pike recursively to scan sub folders

Is your feature request related to a problem? Please describe.
We have a GitHub repo for terraform but with multiple sub-folders for managing different state files. We can only have one role that is assumed by the GH runner so we need to run Pike recursively against the whole GH repo to produce a policy that will allow us to execute TF again any sub folder.

Describe the solution you'd like
run pike to scan all sub folders

Describe alternatives you've considered
Running if for 39 directories individually and manually combining the output

Get default region from aws creds

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Update Readme policy section automatically like terraform-docs

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Unable to Get the Complete Policy Permission Details - pike version v0.2.104

Describe the bug

Unable to Get the Complete Policy Permission Details required for the specific terraform action ( especially in EC2, EKS,S3, SNS )

To Reproduce
Steps to reproduce the behavior:

./pike scan -d .

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS] - MAC
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22] - v0.2.104

Smartphone (please complete the following information):

  • NA
  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Tagging?

Describe the bug
I noticed that when I run a plan in terraform against AWS resources, I need to be able to create or update tags.
When I run a pike scan, it does not tell me that I need to update tags.

To Reproduce
So for instance, if you create an Autoscaling Group & have something like this in the repo:

locals {
standard_tags = {
Repo = "my-asg-repo"
CreatedBy = "Terraform"
Environment = "${var.namespace}-${var.stage}"
}
}

Expected behavior
when I run pike scanner I get this output:

policy = jsonencode({
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"autoscaling:CreateAutoScalingGroup",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:DeletePolicy",
"autoscaling:DescribeAdjustmentTypes",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeScalingActivities",
"autoscaling:DescribeTerminationPolicyTypes",
"autoscaling:ExecutePolicy",
"autoscaling:PutScalingPolicy",
"autoscaling:UpdateAutoScalingGroup"
],
"Resource": [
"*"
]
},

however, if I run a plan/apply, I get permission denied on this: "autoscaling:CreateOrUpdateTags"

So I have to add this to the IAM Policy manually, then my apply will work.

Desktop (please complete the following information):

  • OS: linux or windows so far..

Add any other context about the problem here.
this may not be limited to autoscaling, for instance I have an S3 repo where I need to tag the buckets too, but that doesn't show up.

I saw this in another comment, is this a bug or an enhancement request?

Thanks

support for gcp

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Add support for Pulumi

Is your feature request related to a problem? Please describe.
Pulumi is growing more popular throughout the platform engineering space, and is our preferred IAC tool. Would be great to get pike support for pulumi

Describe the solution you'd like
For pike to integrate with pulumi as it does terraform

Describe alternatives you've considered
Considered implementing a similar in-house tool

Additional context
There's something called the pulumi terraform bridge which could be of assistance potentially

Allow pike to run against plan-file to get realistic IAM policy (not maximum)

Is your feature request related to a problem? Please describe.

When running against terraform configs, pike does not take into account what resources will actually be created and suggest maximum policy.

Describe the solution you'd like

pike -plan-file plan.json scan-plan-file or something like that

Describe alternatives you've considered

Don't use pike. :)


Example 1

$ git clone https://github.com/terraform-aws-modules/terraform-aws-acm
$ cd examples/complete-dns-validation
$ pike -d . scan         
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "route53:CreateHostedZone",
                "route53:DeleteHostedZone",
                "route53:GetChange",
                "route53:GetHostedZone",
                "route53:ListHostedZones",
                "route53:ListResourceRecordSets",
                "route53:ListTagsForResource"
            ],
            "Resource": "*"
        }
    ]
}

It does not include acm:... statements because they are related by the module "acm" (sourced from ../../).


Example 2:

$ git clone https://github.com/terraform-aws-modules/terraform-aws-lambda
$ cd terraform-aws-lambda
$ pike -d . scan         
{
    "Version": "2012-10-17",
    "Statement": [
        # ... omitted
        {
            "Sid": "VisualEditor11",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:CreateSecret",
                "secretsmanager:DeleteSecret",
                "secretsmanager:DescribeSecret",
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:PutSecretValue"
            ],
            "Resource": "*"
        },
        # ... omitted
    ]
}

Q: Where does secretsmanager:... come from? It has been mentioned just in one of the examples (examples/event-source-mapping/main.tf)?

I am not sure these issues are connected, TBH :)

scan url

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

ecs:ModifyCluster does not exist

Describe the bug
ecs:ModifyCluster - this is not an existing permission, perhaps this should be set to ecs:UpdateCluster

To Reproduce
Steps to reproduce the behavior:

Create a resource such as resource "aws_ecs_task_definition" "task" in terraform

Expected behavior
Permissions are correct

Screenshots
image

Cheers

GitHub Action

Is your feature request related to a problem? Please describe.

Contributors to a repository may not update a README with permissions to deploy a Terraform module.

Describe the solution you'd like

Allow users to streamline the process of updating a projects README by creating a GitHub action that will automatically run Pike and commit to a PR.

Describe alternatives you've considered

Using pre-commit hooks - but this requires dependencies on a users machine.

Additional context

Terraform Docs does something similar here

generate azure role with make

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Policy validator

compare you policy requirement with a deployed policy and show differences

target a single file

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

SNS:CreateTopic missing + possibly others..

Describe the bug
Hello good sir...

I added a resource for SNS notifications & noticed I didn't have permission, when I ran a pike scan, this was not picked up...

To Reproduce
in a TF repo, add in something like this:

module "mail_notification" {
source = "geekcell/sns-email-notification/aws"
version = "1.0.2"

email_addresses = ["[email protected]"]
name = "My_Alert"
}

Expected behavior
SNS permissions are shown..

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
In the end, I had to add the following permissions using the module above if it helps!

            "SNS:CreateTopic",
            "SNS:DeleteTopic",
            "SNS:GetSubscriptionAttributes",
            "SNS:GetTopicAttributes",
            "SNS:ListTagsForResource",
            "SNS:Publish",
            "SNS:SetTopicAttributes",
            "SNS:Subscribe",
            "SNS:TagResource",
            "SNS:Unsubscribe",

Build a scratch container with pike in

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

azurerm endpoint permission on "PrivateEndpointConnectionsApproval/action",

Azure rm endpoint can connect to many different endpoint type and each needs a different permission e.g. a redis cache requires "Microsoft.Cache/redis/PrivateEndpointConnectionsApproval/action".

So you can either add them all, none or somehow inspect the endpoint resource to determine what it needs:
`resource "azurerm_private_endpoint" "pike" {
resource_group_name = "pike"
location = "uksouth"
subnet_id = "/subscriptions/037ce662-dfc1-4b8b-a8a7-6c414b540ed6/resourceGroups/pike/providers/Microsoft.Network/virtualNetworks/pike/subnets/pike"
name = "pike"
private_service_connection {
private_connection_resource_id = azurerm_redis_cache.pike.id
is_manual_connection = false
name = "cachy"
subresource_names = [
"redisCache",
]
}

private_dns_zone_group {
  name                 = "default"
  private_dns_zone_ids = ["/subscriptions/037ce662-dfc1-4b8b-a8a7-6c414b540ed6/resourceGroups/pike/providers/Microsoft.Network/privateDnsZones/private.beer"]
}

timeouts {

}
tags = {pike="permission" }

}`

panic: runtime error: index out of range [0] with length 0

Thanks for your project.

Describe the bug
pike run on level1 of level1/level2 projects

To Reproduce

pike -d ./myproject/ scan

panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
github.com/jameswoolfenden/pike/src.GetResources({0xc0000d8b80, 0x71})
/home/runner/work/pike/pike/src/data.go:53 +0x526
github.com/jameswoolfenden/pike/src.MakePolicy({0x7ffd579ea1b1, 0xe}, {0x0, 0x0}, {0x0, 0x0}, 0x0)
/home/runner/work/pike/pike/src/scan.go:106 +0x68b
github.com/jameswoolfenden/pike/src.Scan({0x7ffd579ea1b1, 0x0}, {0x0, 0xed22c0}, {0x0, 0xc0002009b0}, 0x40)
/home/runner/work/pike/pike/src/scan.go:23 +0x2f
main.main.func1(0xc0000c9200)
/home/runner/work/pike/pike/main.go:80 +0x45
github.com/urfave/cli/v2.(*Command).Run(0xc0000c9200, 0xc000155080)
/home/runner/go/pkg/mod/github.com/urfave/cli/[email protected]/command.go:169 +0x6be
github.com/urfave/cli/v2.(*App).RunContext(0xc00015e1a0, {0xb10390, 0xc0000ae020}, {0xc0000aa000, 0x4, 0x4})
/home/runner/go/pkg/mod/github.com/urfave/cli/[email protected]/app.go:341 +0x89c
github.com/urfave/cli/v2.(*App).Run(...)
/home/runner/go/pkg/mod/github.com/urfave/cli/[email protected]/app.go:247
main.main()
/home/runner/work/pike/pike/main.go:127 +0x10d2

Expected behavior
No crash, aggregation of sub-projects permissions

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Amazon Linux 2
  • pike: latest version

License?

Hi Team, this is a very useful project. I wonder what open source license does this project use? Thank you!

handle modules - init to be included in scan

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.