mirror of
https://github.com/strongdm/comply
synced 2025-12-16 11:14:57 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
351c47e381 | ||
|
|
8f5a63db53 | ||
|
|
e289d6d8f4 | ||
|
|
a66764470c | ||
|
|
84e439e7cc | ||
|
|
dbe49a09b3 | ||
|
|
73bebe0202 | ||
|
|
f5f7c08b73 | ||
|
|
b2276f9e54 | ||
|
|
f1b5bbeff9 | ||
|
|
b7acb1eecf |
33
example/controls/README.md
Normal file
33
example/controls/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Controls
|
||||||
|
|
||||||
|
Controls explicitly state a specific action that the organization will take to enforce a Policy goal.
|
||||||
|
|
||||||
|
## Format
|
||||||
|
```
|
||||||
|
name: Access Control Procedures
|
||||||
|
family: Access Control
|
||||||
|
identifier: AC-2
|
||||||
|
governingPolicy:
|
||||||
|
- policyName: Access Onboarding and Termination
|
||||||
|
policyID: SDM-AOTP
|
||||||
|
policyClause: 1.1
|
||||||
|
owner: Director, Security & Compliance
|
||||||
|
published: 2020-01-01
|
||||||
|
targets:
|
||||||
|
TSC 2017:
|
||||||
|
- CC6.1
|
||||||
|
- CC6.2
|
||||||
|
- CC6.3
|
||||||
|
NIST 800-53:
|
||||||
|
- AC-1
|
||||||
|
revisions:
|
||||||
|
- date: Sep 1 2020
|
||||||
|
comment: Initial documentation of control
|
||||||
|
---
|
||||||
|
1. Develop, document, and disseminate to all employees:
|
||||||
|
|
||||||
|
1. Organizational access control policy that:
|
||||||
|
|
||||||
|
1. Addresses purpose, scope, roles, responsibilities, management commitment, coordination among organizational entities, and compliance; and
|
||||||
|
|
||||||
|
```
|
||||||
@@ -66,7 +66,7 @@ html lang=en
|
|||||||
a onclick="javascript:show('procedures')" Procedures
|
a onclick="javascript:show('procedures')" Procedures
|
||||||
li.top-nav.standards
|
li.top-nav.standards
|
||||||
strong
|
strong
|
||||||
a onclick="javascript:show('standards')" Standards
|
a onclick="javascript:show('frameworks')" Frameworks
|
||||||
/ li.top-nav.evidence
|
/ li.top-nav.evidence
|
||||||
/ a onclick="javascript:show('evidence')" Evidence Vault
|
/ a onclick="javascript:show('evidence')" Evidence Vault
|
||||||
#overview.section.top-nav.container.content
|
#overview.section.top-nav.container.content
|
||||||
@@ -76,17 +76,17 @@ html lang=en
|
|||||||
.columns.is-vcentered
|
.columns.is-vcentered
|
||||||
.column.is-one-third
|
.column.is-one-third
|
||||||
div
|
div
|
||||||
p.subtitle.is-3.has-text-centered Control Tracking
|
p.subtitle.is-3.has-text-centered CriterionTracking
|
||||||
.column.has-text-centered
|
.column.has-text-centered
|
||||||
div
|
div
|
||||||
p.heading Satisfied Controls
|
p.heading Satisfied Criteria
|
||||||
p.title
|
p.title
|
||||||
{{.Stats.ControlsSatisfied}}
|
{{.Stats.CriteriaSatisfied}}
|
||||||
.column.has-text-centered
|
.column.has-text-centered
|
||||||
div
|
div
|
||||||
p.heading Total Controls
|
p.heading Total Controls
|
||||||
p.title
|
p.title
|
||||||
{{.Stats.ControlsTotal}}
|
{{.Stats.CriteriaTotal}}
|
||||||
.columns.is-vcentered
|
.columns.is-vcentered
|
||||||
.column.is-one-third
|
.column.is-one-third
|
||||||
div
|
div
|
||||||
@@ -191,19 +191,19 @@ html lang=en
|
|||||||
blockquote
|
blockquote
|
||||||
h3
|
h3
|
||||||
p
|
p
|
||||||
strong Standards
|
strong Frameworks
|
||||||
| specify the controls satisfied by the compliance program.
|
| specify the Framework Criteria satisfied by the compliance program.
|
||||||
table.table.is-size-4.is-fullwidth
|
table.table.is-size-4.is-fullwidth
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th Control Key
|
th CriterionKey
|
||||||
th Name
|
th Name
|
||||||
th Satisfied?
|
th Satisfied?
|
||||||
th Satisfied By
|
th Satisfied By
|
||||||
tbody
|
tbody
|
||||||
{{range .Controls }}
|
{{range .Criteria}}
|
||||||
tr
|
tr
|
||||||
td {{.ControlKey}}
|
td {{.criteriaKey}}
|
||||||
td
|
td
|
||||||
strong {{.Name}}
|
strong {{.Name}}
|
||||||
.subtitle {{.Description}}
|
.subtitle {{.Description}}
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -33,6 +33,7 @@ require (
|
|||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/robfig/cron v1.2.0
|
github.com/robfig/cron v1.2.0
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
|
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
|
||||||
github.com/trivago/tgo v1.0.7 // indirect
|
github.com/trivago/tgo v1.0.7 // indirect
|
||||||
|
|||||||
9
go.sum
9
go.sum
@@ -124,13 +124,16 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
|||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
||||||
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||||
@@ -186,6 +189,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
|||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
@@ -234,9 +238,11 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
|
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
|
||||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
@@ -271,6 +277,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
|
|||||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
||||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||||
@@ -423,12 +430,14 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||||||
github.com/rogpeppe/go-internal v1.5.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.5.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6 h1:tlXG832s5pa9x9Gs3Rp2rTvEqjiDEuETUOSfBEiTcns=
|
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6 h1:tlXG832s5pa9x9Gs3Rp2rTvEqjiDEuETUOSfBEiTcns=
|
||||||
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/sanity-io/litter v1.3.0/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0=
|
github.com/sanity-io/litter v1.3.0/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
var todoCommand = cli.Command{
|
var todoCommand = cli.Command{
|
||||||
Name: "todo",
|
Name: "todo",
|
||||||
Usage: "list declared vs satisfied compliance controls",
|
Usage: "list declared vs satisfied compliance criteria",
|
||||||
Action: todoAction,
|
Action: todoAction,
|
||||||
Before: projectMustExist,
|
Before: projectMustExist,
|
||||||
}
|
}
|
||||||
@@ -24,42 +24,42 @@ func todoAction(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
w := tablewriter.NewWriter(os.Stdout)
|
w := tablewriter.NewWriter(os.Stdout)
|
||||||
w.SetHeader([]string{"Standard", "Control", "Satisfied?", "Name"})
|
w.SetHeader([]string{"Framework", "Criterion", "Satisfied?", "Name"})
|
||||||
|
|
||||||
type row struct {
|
type row struct {
|
||||||
standard string
|
framework string
|
||||||
controlKey string
|
criterionKey string
|
||||||
satisfied string
|
satisfied string
|
||||||
controlName string
|
criterionName string
|
||||||
}
|
}
|
||||||
|
|
||||||
satisfied := model.ControlsSatisfied(d)
|
satisfied := model.CriteriaSatisfied(d)
|
||||||
|
|
||||||
var rows []row
|
var rows []row
|
||||||
for _, std := range d.Standards {
|
for _, std := range d.Frameworks {
|
||||||
for id, c := range std.Controls {
|
for id, c := range std.Criteria{
|
||||||
sat := "NO"
|
sat := "NO"
|
||||||
if _, ok := satisfied[id]; ok {
|
if _, ok := satisfied[id]; ok {
|
||||||
sat = color.GreenString("YES")
|
sat = color.GreenString("YES")
|
||||||
}
|
}
|
||||||
|
|
||||||
rows = append(rows, row{
|
rows = append(rows, row{
|
||||||
standard: std.Name,
|
framework: std.Name,
|
||||||
controlKey: id,
|
criterionKey: id,
|
||||||
satisfied: sat,
|
satisfied: sat,
|
||||||
controlName: c.Name,
|
criterionName: c.Name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(rows, func(i, j int) bool {
|
sort.Slice(rows, func(i, j int) bool {
|
||||||
return rows[i].controlKey < rows[j].controlKey
|
return rows[i].criterionKey < rows[j].criterionKey
|
||||||
})
|
})
|
||||||
|
|
||||||
w.SetAutoWrapText(false)
|
w.SetAutoWrapText(false)
|
||||||
|
|
||||||
for _, r := range rows {
|
for _, r := range rows {
|
||||||
w.Append([]string{r.standard, r.controlKey, r.satisfied, r.controlName})
|
w.Append([]string{r.framework, r.criterionKey, r.satisfied, r.criterionName})
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Render()
|
w.Render()
|
||||||
|
|||||||
24
internal/model/control.go
Normal file
24
internal/model/control.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"html/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Control struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
ID string `yaml:"identifier"`
|
||||||
|
Family string `yaml:"family"`
|
||||||
|
Owner string `yaml:"owner"`
|
||||||
|
GoverningPolicy []Policy `yaml:"governingPolicy"`
|
||||||
|
Revisions []Revision `yaml:"revisions"`
|
||||||
|
Targets Target `yaml:"targets"`
|
||||||
|
Published string `yaml:"published"`
|
||||||
|
|
||||||
|
FullPath string
|
||||||
|
OutputFilename string
|
||||||
|
ModifiedAt time.Time
|
||||||
|
|
||||||
|
Body string
|
||||||
|
BodyHTML template.HTML
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ type Document struct {
|
|||||||
|
|
||||||
Revisions []Revision `yaml:"majorRevisions"`
|
Revisions []Revision `yaml:"majorRevisions"`
|
||||||
Satisfies Satisfaction `yaml:"satisfies"`
|
Satisfies Satisfaction `yaml:"satisfies"`
|
||||||
|
Targets Target `yaml:"targets"`
|
||||||
FullPath string
|
FullPath string
|
||||||
OutputFilename string
|
OutputFilename string
|
||||||
ModifiedAt time.Time
|
ModifiedAt time.Time
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
type Control struct {
|
type Criterion struct {
|
||||||
Family string `yaml:"family"`
|
Family string `yaml:"family"`
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Description string `yaml:"description"`
|
Description string `yaml:"description"`
|
||||||
|
|
||||||
|
Satisfied bool
|
||||||
|
SatisfiedBy []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Standard struct {
|
type Framework struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Controls map[string]Control `yaml:",inline"`
|
Criteria map[string]Criterion `yaml:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ControlsSatisfied determines the unique controls currently satisfied by all Narratives, Policies, and Procedures
|
type Target map[string][]string
|
||||||
func ControlsSatisfied(data *Data) map[string][]string {
|
|
||||||
|
// CriteriaSatisfied determines the unique criteria currently satisfied by all Narratives, Policies, and Procedures
|
||||||
|
func CriteriaSatisfied(data *Data) map[string][]string {
|
||||||
satisfied := make(map[string][]string)
|
satisfied := make(map[string][]string)
|
||||||
|
|
||||||
appendSatisfaction := func(in map[string][]string, k string, v string) []string {
|
appendSatisfaction := func(in map[string][]string, k string, v string) []string {
|
||||||
@@ -25,22 +30,29 @@ func ControlsSatisfied(data *Data) map[string][]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range data.Narratives {
|
for _, n := range data.Narratives {
|
||||||
for _, controlKeys := range n.Satisfies {
|
for _, criteriaKeys := range n.Satisfies {
|
||||||
for _, key := range controlKeys {
|
for _, key := range criteriaKeys {
|
||||||
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
|
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, n := range data.Policies {
|
for _, n := range data.Policies {
|
||||||
for _, controlKeys := range n.Satisfies {
|
for _, criteriaKeys := range n.Satisfies {
|
||||||
for _, key := range controlKeys {
|
for _, key := range criteriaKeys {
|
||||||
|
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, n := range data.Controls {
|
||||||
|
for _, criteriaKeys := range n.Targets {
|
||||||
|
for _, key := range criteriaKeys {
|
||||||
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
|
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, n := range data.Procedures {
|
for _, n := range data.Procedures {
|
||||||
for _, controlKeys := range n.Satisfies {
|
for _, criteriaKeys := range n.Satisfies {
|
||||||
for _, key := range controlKeys {
|
for _, key := range criteriaKeys {
|
||||||
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
|
satisfied[key] = appendSatisfaction(satisfied, key, n.OutputFilename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,11 +26,15 @@ func ReadData() (*Data, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
controls, err := ReadControls()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
procedures, err := ReadProcedures()
|
procedures, err := ReadProcedures()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
standards, err := ReadStandards()
|
frameworks, err := ReadFrameworks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -39,8 +43,9 @@ func ReadData() (*Data, error) {
|
|||||||
Tickets: tickets,
|
Tickets: tickets,
|
||||||
Narratives: narratives,
|
Narratives: narratives,
|
||||||
Policies: policies,
|
Policies: policies,
|
||||||
|
Controls: controls,
|
||||||
Procedures: procedures,
|
Procedures: procedures,
|
||||||
Standards: standards,
|
Frameworks: frameworks,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,27 +72,27 @@ func tickets(rawTickets []string) ([]*Ticket, error) {
|
|||||||
return tickets, nil
|
return tickets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadStandards loads standard definitions from the filesystem.
|
// ReadFrameworks loads standard definitions from the filesystem.
|
||||||
func ReadStandards() ([]*Standard, error) {
|
func ReadFrameworks() ([]*Framework, error) {
|
||||||
var standards []*Standard
|
var frameworks []*Framework
|
||||||
|
|
||||||
files, err := path.Standards()
|
files, err := path.Frameworks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "unable to enumerate paths")
|
return nil, errors.Wrap(err, "unable to enumerate paths")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
s := &Standard{}
|
s := &Framework{}
|
||||||
sBytes, err := ioutil.ReadFile(f.FullPath)
|
sBytes, err := ioutil.ReadFile(f.FullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "unable to read "+f.FullPath)
|
return nil, errors.Wrap(err, "unable to read "+f.FullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
yaml.Unmarshal(sBytes, &s)
|
yaml.Unmarshal(sBytes, &s)
|
||||||
standards = append(standards, s)
|
frameworks = append(frameworks, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return standards, nil
|
return frameworks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadNarratives loads narrative descriptions from the filesystem.
|
// ReadNarratives loads narrative descriptions from the filesystem.
|
||||||
@@ -166,6 +171,31 @@ func ReadPolicies() ([]*Document, error) {
|
|||||||
return policies, nil
|
return policies, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadControls loads control documents from the filesystem
|
||||||
|
func ReadControls() ([]*Control, error) {
|
||||||
|
var controls []*Control
|
||||||
|
|
||||||
|
files, err := path.Controls()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unable to enumerate paths")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
c := &Control{}
|
||||||
|
mdmd := loadMDMD(f.FullPath)
|
||||||
|
err = yaml.Unmarshal([]byte(mdmd.yaml), &c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unable to parse "+f.FullPath)
|
||||||
|
}
|
||||||
|
c.Body = mdmd.body
|
||||||
|
c.FullPath = f.FullPath
|
||||||
|
c.ModifiedAt = f.Info.ModTime()
|
||||||
|
c.OutputFilename = fmt.Sprintf("%s-%s.pdf", config.Config().FilePrefix, c.ID)
|
||||||
|
controls = append(controls, c)
|
||||||
|
}
|
||||||
|
return controls, nil
|
||||||
|
}
|
||||||
|
|
||||||
type metadataMarkdown struct {
|
type metadataMarkdown struct {
|
||||||
yaml string
|
yaml string
|
||||||
body string
|
body string
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
type Data struct {
|
type Data struct {
|
||||||
Standards []*Standard
|
Frameworks []*Framework
|
||||||
Narratives []*Document
|
Narratives []*Document
|
||||||
Policies []*Document
|
Policies []*Document
|
||||||
|
Controls []*Control
|
||||||
Procedures []*Procedure
|
Procedures []*Procedure
|
||||||
Tickets []*Ticket
|
Tickets []*Ticket
|
||||||
Audits []*Audit
|
Audits []*Audit
|
||||||
|
|||||||
7
internal/model/policy.go
Normal file
7
internal/model/policy.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Policy struct {
|
||||||
|
Name string `yaml:"policyName"`
|
||||||
|
ID string `yaml:"policyID"`
|
||||||
|
Clause string `yaml:"policyClause"`
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ type Procedure struct {
|
|||||||
|
|
||||||
Revisions []Revision `yaml:"majorRevisions"`
|
Revisions []Revision `yaml:"majorRevisions"`
|
||||||
Satisfies Satisfaction `yaml:"satisfies"`
|
Satisfies Satisfaction `yaml:"satisfies"`
|
||||||
|
Targets Target `yaml:"targets"`
|
||||||
FullPath string
|
FullPath string
|
||||||
OutputFilename string
|
OutputFilename string
|
||||||
ModifiedAt time.Time
|
ModifiedAt time.Time
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ type File struct {
|
|||||||
Info os.FileInfo
|
Info os.FileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standards lists all standard files.
|
// Frameworks lists all standard files.
|
||||||
func Standards() ([]File, error) {
|
func Frameworks() ([]File, error) {
|
||||||
return filesFor("standards", "yml")
|
return filesFor("frameworks", "yaml")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Narratives lists all narrative files.
|
// Narratives lists all narrative files.
|
||||||
@@ -30,6 +30,11 @@ func Policies() ([]File, error) {
|
|||||||
return filesFor("policies", "md")
|
return filesFor("policies", "md")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Controls lists all control files.
|
||||||
|
func Controls() ([]File, error) {
|
||||||
|
return filesFor("controls", "md")
|
||||||
|
}
|
||||||
|
|
||||||
// Procedures lists all procedure files.
|
// Procedures lists all procedure files.
|
||||||
func Procedures() ([]File, error) {
|
func Procedures() ([]File, error) {
|
||||||
return filesFor("procedures", "md")
|
return filesFor("procedures", "md")
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package render
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"time"
|
"time"
|
||||||
|
"html/template"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/strongdm/comply/internal/config"
|
"github.com/strongdm/comply/internal/config"
|
||||||
"github.com/strongdm/comply/internal/model"
|
"github.com/strongdm/comply/internal/model"
|
||||||
|
|
||||||
|
"github.com/russross/blackfriday/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type project struct {
|
type project struct {
|
||||||
@@ -17,7 +19,9 @@ type project struct {
|
|||||||
|
|
||||||
type stats struct {
|
type stats struct {
|
||||||
ControlsTotal int
|
ControlsTotal int
|
||||||
ControlsSatisfied int
|
|
||||||
|
CriteriaTotal int
|
||||||
|
CriteriaSatisfied int
|
||||||
|
|
||||||
ProcedureTotal int
|
ProcedureTotal int
|
||||||
ProcedureOpen int
|
ProcedureOpen int
|
||||||
@@ -35,16 +39,16 @@ type renderData struct {
|
|||||||
Stats *stats
|
Stats *stats
|
||||||
Narratives []*model.Document
|
Narratives []*model.Document
|
||||||
Policies []*model.Document
|
Policies []*model.Document
|
||||||
|
Controls []*model.Control
|
||||||
Procedures []*model.Procedure
|
Procedures []*model.Procedure
|
||||||
Standards []*model.Standard
|
Frameworks []*model.Framework
|
||||||
Tickets []*model.Ticket
|
Tickets []*model.Ticket
|
||||||
Controls []*control
|
|
||||||
Links *model.TicketLinks
|
Links *model.TicketLinks
|
||||||
}
|
}
|
||||||
|
|
||||||
type control struct {
|
type criterion struct {
|
||||||
Standard string
|
Framework string
|
||||||
ControlKey string
|
CriteriaKey string
|
||||||
Name string
|
Name string
|
||||||
Description string
|
Description string
|
||||||
Satisfied bool
|
Satisfied bool
|
||||||
@@ -63,36 +67,27 @@ func load() (*model.Data, *renderData, error) {
|
|||||||
Name: fmt.Sprintf("%s Compliance Program", cfg.Name),
|
Name: fmt.Sprintf("%s Compliance Program", cfg.Name),
|
||||||
}
|
}
|
||||||
|
|
||||||
satisfied := model.ControlsSatisfied(modelData)
|
satisfied := model.CriteriaSatisfied(modelData)
|
||||||
controls := make([]*control, 0)
|
for _, framework := range modelData.Frameworks {
|
||||||
for _, standard := range modelData.Standards {
|
for key, c := range framework.Criteria{
|
||||||
for key, c := range standard.Controls {
|
|
||||||
satisfactions, ok := satisfied[key]
|
satisfactions, ok := satisfied[key]
|
||||||
satisfied := ok && len(satisfactions) > 0
|
satisfied := ok && len(satisfactions) > 0
|
||||||
controls = append(controls, &control{
|
c.Satisfied = satisfied
|
||||||
Standard: standard.Name,
|
c.SatisfiedBy = satisfactions
|
||||||
ControlKey: key,
|
framework.Criteria[key] = c
|
||||||
Name: c.Name,
|
|
||||||
Description: c.Description,
|
|
||||||
Satisfied: satisfied,
|
|
||||||
SatisfiedBy: satisfactions,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Slice(controls, func(i, j int) bool {
|
|
||||||
return controls[i].ControlKey < controls[j].ControlKey
|
|
||||||
})
|
|
||||||
|
|
||||||
rd := &renderData{}
|
rd := &renderData{}
|
||||||
rd.Narratives = modelData.Narratives
|
rd.Narratives = modelData.Narratives
|
||||||
rd.Policies = modelData.Policies
|
rd.Policies = modelData.Policies
|
||||||
|
rd.Controls = modelData.Controls
|
||||||
rd.Procedures = modelData.Procedures
|
rd.Procedures = modelData.Procedures
|
||||||
rd.Standards = modelData.Standards
|
rd.Frameworks = modelData.Frameworks
|
||||||
rd.Tickets = modelData.Tickets
|
rd.Tickets = modelData.Tickets
|
||||||
rd.Links = &model.TicketLinks{}
|
rd.Links = &model.TicketLinks{}
|
||||||
rd.Project = project
|
rd.Project = project
|
||||||
rd.Name = project.OrganizationName
|
rd.Name = project.OrganizationName
|
||||||
rd.Controls = controls
|
|
||||||
|
|
||||||
ts, err := config.Config().TicketSystem()
|
ts, err := config.Config().TicketSystem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -114,6 +109,12 @@ func loadWithStats() (*model.Data, *renderData, error) {
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert the markdown body of each control to HTML
|
||||||
|
for _, n := range modelData.Controls {
|
||||||
|
b := []byte(n.Body)
|
||||||
|
n.BodyHTML = template.HTML(blackfriday.Run(b))
|
||||||
|
}
|
||||||
|
|
||||||
addStats(modelData, renderData)
|
addStats(modelData, renderData)
|
||||||
return modelData, renderData, nil
|
return modelData, renderData, nil
|
||||||
}
|
}
|
||||||
@@ -121,13 +122,14 @@ func loadWithStats() (*model.Data, *renderData, error) {
|
|||||||
func addStats(modelData *model.Data, renderData *renderData) {
|
func addStats(modelData *model.Data, renderData *renderData) {
|
||||||
stats := &stats{}
|
stats := &stats{}
|
||||||
|
|
||||||
satisfied := model.ControlsSatisfied(modelData)
|
satisfied := model.CriteriaSatisfied(modelData)
|
||||||
|
stats.ControlsTotal += len(renderData.Controls)
|
||||||
|
|
||||||
for _, std := range renderData.Standards {
|
for _, std := range renderData.Frameworks {
|
||||||
stats.ControlsTotal += len(std.Controls)
|
stats.CriteriaTotal += len(std.Criteria)
|
||||||
for controlKey := range std.Controls {
|
for criteriaKey := range std.Criteria{
|
||||||
if _, ok := satisfied[controlKey]; ok {
|
if _, ok := satisfied[criteriaKey]; ok {
|
||||||
stats.ControlsSatisfied++
|
stats.CriteriaSatisfied++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func preprocessDoc(data *renderData, pol *model.Document, fullPath string) error
|
|||||||
for standard, keys := range pol.Satisfies {
|
for standard, keys := range pol.Satisfies {
|
||||||
rows += fmt.Sprintf("| %s | %s |\n", standard, strings.Join(keys, ", "))
|
rows += fmt.Sprintf("| %s | %s |\n", standard, strings.Join(keys, ", "))
|
||||||
}
|
}
|
||||||
satisfiesTable = fmt.Sprintf("|Standard|Controls Satisfied|\n|-------+--------------------------------------------|\n%s\nTable: Control satisfaction\n", rows)
|
satisfiesTable = fmt.Sprintf("|Framework|Criteria Satisfied|\n|-------+--------------------------------------------|\n%s\nTable: Criterion satisfaction\n", rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pol.Revisions) > 0 {
|
if len(pol.Revisions) > 0 {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ func watch(errCh chan error) {
|
|||||||
b.Add("./templates/")
|
b.Add("./templates/")
|
||||||
b.Add("./narratives/")
|
b.Add("./narratives/")
|
||||||
b.Add("./policies/")
|
b.Add("./policies/")
|
||||||
|
b.Add("./controls/")
|
||||||
b.Add("./procedures/")
|
b.Add("./procedures/")
|
||||||
|
|
||||||
b.Add("./.comply/")
|
b.Add("./.comply/")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
33
themes/comply-blank/controls/README.md
Normal file
33
themes/comply-blank/controls/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Controls
|
||||||
|
|
||||||
|
Controls explicitly state a specific action that the organization will take to enforce a Policy goal.
|
||||||
|
|
||||||
|
## Format
|
||||||
|
```
|
||||||
|
name: Access Control Procedures
|
||||||
|
family: Access Control
|
||||||
|
identifier: AC-2
|
||||||
|
governingPolicy:
|
||||||
|
- policyName: Access Onboarding and Termination
|
||||||
|
policyID: SDM-AOTP
|
||||||
|
policyClause: 1.1
|
||||||
|
owner: Director, Security & Compliance
|
||||||
|
published: 2020-01-01
|
||||||
|
targets:
|
||||||
|
TSC 2017:
|
||||||
|
- CC6.1
|
||||||
|
- CC6.2
|
||||||
|
- CC6.3
|
||||||
|
NIST 800-53:
|
||||||
|
- AC-1
|
||||||
|
revisions:
|
||||||
|
- date: Sep 1 2020
|
||||||
|
comment: Initial documentation of control
|
||||||
|
---
|
||||||
|
1. Develop, document, and disseminate to all employees:
|
||||||
|
|
||||||
|
1. Organizational access control policy that:
|
||||||
|
|
||||||
|
1. Addresses purpose, scope, roles, responsibilities, management commitment, coordination among organizational entities, and compliance; and
|
||||||
|
|
||||||
|
```
|
||||||
0
themes/comply-blank/frameworks/.gitkeep
Normal file
0
themes/comply-blank/frameworks/.gitkeep
Normal file
@@ -66,7 +66,7 @@ html lang=en
|
|||||||
a onclick="javascript:show('procedures')" Procedures
|
a onclick="javascript:show('procedures')" Procedures
|
||||||
li.top-nav.standards
|
li.top-nav.standards
|
||||||
strong
|
strong
|
||||||
a onclick="javascript:show('standards')" Standards
|
a onclick="javascript:show('frameworks')" Frameworks
|
||||||
/ li.top-nav.evidence
|
/ li.top-nav.evidence
|
||||||
/ a onclick="javascript:show('evidence')" Evidence Vault
|
/ a onclick="javascript:show('evidence')" Evidence Vault
|
||||||
#overview.section.top-nav.container.content
|
#overview.section.top-nav.container.content
|
||||||
@@ -76,17 +76,17 @@ html lang=en
|
|||||||
.columns.is-vcentered
|
.columns.is-vcentered
|
||||||
.column.is-one-third
|
.column.is-one-third
|
||||||
div
|
div
|
||||||
p.subtitle.is-3.has-text-centered Control Tracking
|
p.subtitle.is-3.has-text-centered CriterionTracking
|
||||||
.column.has-text-centered
|
.column.has-text-centered
|
||||||
div
|
div
|
||||||
p.heading Satisfied Controls
|
p.heading Satisfied Criteria
|
||||||
p.title
|
p.title
|
||||||
{{.Stats.ControlsSatisfied}}
|
{{.Stats.CriteriaSatisfied}}
|
||||||
.column.has-text-centered
|
.column.has-text-centered
|
||||||
div
|
div
|
||||||
p.heading Total Controls
|
p.heading Total Controls
|
||||||
p.title
|
p.title
|
||||||
{{.Stats.ControlsTotal}}
|
{{.Stats.CriteriaTotal}}
|
||||||
.columns.is-vcentered
|
.columns.is-vcentered
|
||||||
.column.is-one-third
|
.column.is-one-third
|
||||||
div
|
div
|
||||||
@@ -187,23 +187,23 @@ html lang=en
|
|||||||
td On demand
|
td On demand
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
#standards.section.top-nav.container.content
|
#frameworks.section.top-nav.container.content
|
||||||
blockquote
|
blockquote
|
||||||
h3
|
h3
|
||||||
p
|
p
|
||||||
strong Standards
|
strong Framework Targets
|
||||||
| specify the controls satisfied by the compliance program.
|
| specify the Frameworks and Framework Criteria targeted by the compliance program.
|
||||||
table.table.is-size-4.is-fullwidth
|
table.table.is-size-4.is-fullwidth
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th Control Key
|
th CriterionKey
|
||||||
th Name
|
th Name
|
||||||
th Satisfied?
|
th Satisfied?
|
||||||
th Satisfied By
|
th Satisfied By
|
||||||
tbody
|
tbody
|
||||||
{{range .Controls }}
|
{{range .Criteria}}
|
||||||
tr
|
tr
|
||||||
td {{.ControlKey}}
|
td {{.criteriaKey}}
|
||||||
td
|
td
|
||||||
strong {{.Name}}
|
strong {{.Name}}
|
||||||
.subtitle {{.Description}}
|
.subtitle {{.Description}}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Compliance documents are organized as follows:
|
|||||||
narratives/ Narratives provide an overview of the organization and the compliance environment.
|
narratives/ Narratives provide an overview of the organization and the compliance environment.
|
||||||
policies/ Policies govern the behavior of employees and contractors.
|
policies/ Policies govern the behavior of employees and contractors.
|
||||||
procedures/ Procedures prescribe specific steps that are taken in response to key events.
|
procedures/ Procedures prescribe specific steps that are taken in response to key events.
|
||||||
standards/ Standards specify the controls satisfied by the compliance program.
|
frameworks/ Frameworks specify the control criteria targeted by the compliance program.
|
||||||
templates/ Templates control the output format of the HTML Dashboard and PDF assets.
|
templates/ Templates control the output format of the HTML Dashboard and PDF assets.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
33
themes/comply-soc2/controls/README.md
Normal file
33
themes/comply-soc2/controls/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Controls
|
||||||
|
|
||||||
|
Controls explicitly state a specific action that the organization will take to enforce a Policy goal.
|
||||||
|
|
||||||
|
## Format
|
||||||
|
```
|
||||||
|
name: Access Control Procedures
|
||||||
|
family: Access Control
|
||||||
|
identifier: AC-2
|
||||||
|
governingPolicy:
|
||||||
|
- policyName: Access Onboarding and Termination
|
||||||
|
policyID: SDM-AOTP
|
||||||
|
policyClause: 1.1
|
||||||
|
owner: Director, Security & Compliance
|
||||||
|
published: 2020-01-01
|
||||||
|
targets:
|
||||||
|
TSC 2017:
|
||||||
|
- CC6.1
|
||||||
|
- CC6.2
|
||||||
|
- CC6.3
|
||||||
|
NIST 800-53:
|
||||||
|
- AC-1
|
||||||
|
revisions:
|
||||||
|
- date: Sep 1 2020
|
||||||
|
comment: Initial documentation of control
|
||||||
|
---
|
||||||
|
1. Develop, document, and disseminate to all employees:
|
||||||
|
|
||||||
|
1. Organizational access control policy that:
|
||||||
|
|
||||||
|
1. Addresses purpose, scope, roles, responsibilities, management commitment, coordination among organizational entities, and compliance; and
|
||||||
|
|
||||||
|
```
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Standards
|
# Frameworks
|
||||||
|
|
||||||
All `yaml` files in this directory are assumed to conform to https://github.com/opencontrol/schemas/tree/master/kwalify/standard
|
All `yaml` files in this directory are assumed to conform to https://github.com/opencontrol/schemas/tree/master/kwalify/standard
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Control Environment Narrative
|
name: CriterionEnvironment Narrative
|
||||||
acronym: CEN
|
acronym: CEN
|
||||||
satisfies:
|
satisfies:
|
||||||
TSC:
|
TSC:
|
||||||
@@ -15,7 +15,7 @@ majorRevisions:
|
|||||||
comment: Initial document
|
comment: Initial document
|
||||||
---
|
---
|
||||||
|
|
||||||
# Control Environment Narrative
|
# CriterionEnvironment Narrative
|
||||||
|
|
||||||
The following provides a description of the control structure of {{.Name}}.
|
The following provides a description of the control structure of {{.Name}}.
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ The intent of this description is to enumerate the logical, policy, and procedur
|
|||||||
|
|
||||||
{{.Name}} employs several policy controls to protect confidential data and ensure normal operation of its core product. These policies include, but are not limited to:
|
{{.Name}} employs several policy controls to protect confidential data and ensure normal operation of its core product. These policies include, but are not limited to:
|
||||||
|
|
||||||
- Access Control Policy
|
- Access CriterionPolicy
|
||||||
- Encryption Policy
|
- Encryption Policy
|
||||||
- Office Security Policy
|
- Office Security Policy
|
||||||
- Password Policy
|
- Password Policy
|
||||||
|
|||||||
0
themes/comply-soc2/standards/.gitkeep
Normal file
0
themes/comply-soc2/standards/.gitkeep
Normal file
@@ -66,7 +66,7 @@ html lang=en
|
|||||||
a onclick="javascript:show('procedures')" Procedures
|
a onclick="javascript:show('procedures')" Procedures
|
||||||
li.top-nav.standards
|
li.top-nav.standards
|
||||||
strong
|
strong
|
||||||
a onclick="javascript:show('standards')" Standards
|
a onclick="javascript:show('frameworks')" Frameworks
|
||||||
/ li.top-nav.evidence
|
/ li.top-nav.evidence
|
||||||
/ a onclick="javascript:show('evidence')" Evidence Vault
|
/ a onclick="javascript:show('evidence')" Evidence Vault
|
||||||
#overview.section.top-nav.container.content
|
#overview.section.top-nav.container.content
|
||||||
@@ -76,17 +76,17 @@ html lang=en
|
|||||||
.columns.is-vcentered
|
.columns.is-vcentered
|
||||||
.column.is-one-third
|
.column.is-one-third
|
||||||
div
|
div
|
||||||
p.subtitle.is-3.has-text-centered Control Tracking
|
p.subtitle.is-3.has-text-centered CriterionTracking
|
||||||
.column.has-text-centered
|
.column.has-text-centered
|
||||||
div
|
div
|
||||||
p.heading Satisfied Controls
|
p.heading Satisfied Criteria
|
||||||
p.title
|
p.title
|
||||||
{{.Stats.ControlsSatisfied}}
|
{{.Stats.CriteriaSatisfied}}
|
||||||
.column.has-text-centered
|
.column.has-text-centered
|
||||||
div
|
div
|
||||||
p.heading Total Controls
|
p.heading Total Controls
|
||||||
p.title
|
p.title
|
||||||
{{.Stats.ControlsTotal}}
|
{{.Stats.CriteriaTotal}}
|
||||||
.columns.is-vcentered
|
.columns.is-vcentered
|
||||||
.column.is-one-third
|
.column.is-one-third
|
||||||
div
|
div
|
||||||
@@ -187,23 +187,23 @@ html lang=en
|
|||||||
td On demand
|
td On demand
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
#standards.section.top-nav.container.content
|
#frameworks.section.top-nav.container.content
|
||||||
blockquote
|
blockquote
|
||||||
h3
|
h3
|
||||||
p
|
p
|
||||||
strong Standards
|
strong Framework Targets
|
||||||
| specify the controls satisfied by the compliance program.
|
| specify the Frameworks and Framework Criteria targeted by the compliance program.
|
||||||
table.table.is-size-4.is-fullwidth
|
table.table.is-size-4.is-fullwidth
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th Control Key
|
th CriterionKey
|
||||||
th Name
|
th Name
|
||||||
th Satisfied?
|
th Satisfied?
|
||||||
th Satisfied By
|
th Satisfied By
|
||||||
tbody
|
tbody
|
||||||
{{range .Controls }}
|
{{range .Criteria}}
|
||||||
tr
|
tr
|
||||||
td {{.ControlKey}}
|
td {{.criteriaKey}}
|
||||||
td
|
td
|
||||||
strong {{.Name}}
|
strong {{.Name}}
|
||||||
.subtitle {{.Description}}
|
.subtitle {{.Description}}
|
||||||
|
|||||||
Reference in New Issue
Block a user