├── .babelrc ├── .buffalo.dev.yml ├── .codeclimate.yml ├── .dockerignore ├── .github ├── dependabot.yml └── workflows │ └── go.yml ├── .gitignore ├── Dockerfile ├── Makefile ├── README.md ├── actions ├── actions_test.go ├── api │ ├── admin.go │ ├── certifications.go │ ├── components.go │ ├── render.go │ └── standards.go ├── app.go ├── home_test.go ├── jobs │ └── schedule.go ├── pattenfly_react.go ├── render.go └── workers.go ├── assets ├── OpenShift_on_Azure_Blueprint-FedRAMP_Moderate.docx ├── css │ ├── _buffalo.scss │ └── application.scss ├── images │ ├── favicon-192.png │ ├── favicon.png │ ├── logo.svg │ └── markdown │ │ ├── activitystream.png │ │ ├── tower-user-activity-stream-1-creation.jpg │ │ ├── tower-user-activity-stream-2-creation-detail.jpg │ │ ├── tower-user-activity-stream-3-update.jpg │ │ └── tower-user-activity-stream-4-deletion.jpg ├── js │ └── application.js └── src │ ├── app │ ├── AppLayout │ │ ├── About.tsx │ │ ├── AppLayout.tsx │ │ ├── Navigation.tsx │ │ ├── ProductSelector.tsx │ │ └── Routes.tsx │ ├── NotFound │ │ └── NotFound.tsx │ ├── __snapshots__ │ │ └── app.test.tsx.snap │ ├── app.css │ ├── app.test.tsx │ ├── assets │ │ ├── images │ │ │ ├── RMF-steps-all.png │ │ │ ├── atopathways.png │ │ │ ├── nist-logo-2x.png │ │ │ ├── red-hat-logo-a.png │ │ │ ├── red-hat-logo.png │ │ │ ├── rh-acm.png │ │ │ ├── rh-coreos.png │ │ │ ├── rh-hat.png │ │ │ ├── rh-openshift.png │ │ │ ├── rh-openstack.png │ │ │ ├── rh-rhel.png │ │ │ ├── rh-rhel8.png │ │ │ ├── rh-tower.png │ │ │ └── rh-virtualization.png │ │ └── markdown │ │ │ ├── products │ │ │ ├── ansible-tower │ │ │ │ ├── ICS-500-27.md │ │ │ │ ├── Overview.md │ │ │ │ └── SCAP.md │ │ │ ├── coreos-4 │ │ │ │ ├── Overview.md │ │ │ │ └── SCAP.md │ │ │ ├── identity-management │ │ │ │ └── Overview.md │ │ │ ├── insights │ │ │ │ └── Overview.md │ │ │ ├── openshift-container-platform-3 │ │ │ │ ├── Overview.md │ │ │ │ └── SCAP.md │ │ │ ├── openshift-container-platform-4 │ │ │ │ ├── Overview.md │ │ │ │ └── SCAP.md │ │ │ ├── openshift-dedicated │ │ │ │ └── Overview.md │ │ │ ├── openstack-platform-13 │ │ │ │ ├── Overview.md │ │ │ │ └── SCAP.md │ │ │ ├── rhacm │ │ │ │ └── Overview.md │ │ │ ├── rhel-7 │ │ │ │ ├── Overview.md │ │ │ │ └── SCAP.md │ │ │ ├── rhel-8 │ │ │ │ ├── Overview.md │ │ │ │ ├── SCAP.md │ │ │ │ └── STIG.md │ │ │ ├── virtualization-host │ │ │ │ ├── Overview.md │ │ │ │ └── SCAP.md │ │ │ └── virtualization-manager │ │ │ │ └── Overview.md │ │ │ ├── training-plan.md │ │ │ └── vulnerability-management-plan.md │ ├── ato │ │ ├── Charts │ │ │ ├── BarCharts.tsx │ │ │ ├── CompletionCharts.tsx │ │ │ ├── PieCharts.tsx │ │ │ ├── RadarCharts.tsx │ │ │ ├── StackCharts.tsx │ │ │ └── common.tsx │ │ ├── Documents │ │ │ ├── Documents.tsx │ │ │ ├── Overview.tsx │ │ │ └── SSPTemplates.tsx │ │ ├── GettingStarted.tsx │ │ └── Products │ │ │ ├── DataList.tsx │ │ │ ├── Product.tsx │ │ │ ├── Products.tsx │ │ │ ├── RTMDetail.tsx │ │ │ ├── SatisfiesAccordion.tsx │ │ │ └── Static.tsx │ ├── index.tsx │ ├── lib │ │ ├── Memoize.tsx │ │ ├── api.tsx │ │ ├── csv.tsx │ │ ├── markdown.tsx │ │ ├── opencontrol.tsx │ │ └── querystring.tsx │ ├── routes.tsx │ └── utils │ │ └── utils.ts │ ├── index.tsx │ └── typings.d.ts ├── config ├── buffalo-app.toml └── buffalo-plugins.toml ├── database.yml ├── fixtures └── sample.toml ├── go.mod ├── go.sum ├── grifts ├── db.go └── init.go ├── inflections.json ├── locales └── all.en-us.yaml ├── main.go ├── package.json ├── pkg ├── backend │ └── job │ │ └── job.go ├── cac │ ├── acquire.go │ ├── csv.go │ ├── http.go │ └── rolie.go ├── cac_oscal │ ├── acquire.go │ └── fedramp.go ├── git │ └── easy.go ├── masonry │ ├── acquire.go │ ├── certifications.go │ ├── logical_view.go │ ├── singleton.go │ ├── stats │ │ └── history.go │ └── wrapper.go ├── static │ └── assets.go └── utils │ └── log_writer.go ├── public ├── robots.txt └── srg-to-csv.xslt ├── templates ├── _flash.plush.html ├── application.plush.html └── index.plush.html ├── tsconfig.json ├── webpack.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/env", 4 | "@babel/react" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.buffalo.dev.yml: -------------------------------------------------------------------------------- 1 | app_root: . 2 | ignored_folders: 3 | - vendor 4 | - log 5 | - logs 6 | - assets 7 | - public 8 | - grifts 9 | - tmp 10 | - bin 11 | - node_modules 12 | - .sass-cache 13 | included_extensions: 14 | - .go 15 | - .env 16 | build_path: tmp 17 | build_delay: 200ns 18 | binary_name: ocdb-build 19 | command_flags: [] 20 | enable_colors: true 21 | log_name: buffalo 22 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | fixme: 3 | enabled: true 4 | gofmt: 5 | enabled: true 6 | golint: 7 | enabled: true 8 | govet: 9 | enabled: true 10 | exclude_paths: 11 | - grifts/**/* 12 | - "**/*_test.go" 13 | - "*_test.go" 14 | - "**_test.go" 15 | - logs/* 16 | - public/* 17 | - templates/* 18 | ratings: 19 | paths: 20 | - "**.go" 21 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.log 3 | bin/ 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: gomod 5 | directory: "/" 6 | schedule: 7 | interval: daily 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | on: 3 | push: 4 | branches: [ master ] 5 | pull_request: 6 | branches: [ master ] 7 | jobs: 8 | 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | steps: 13 | 14 | - name: Set up Go 1.14 15 | uses: actions/setup-go@v1 16 | with: 17 | go-version: 1.14 18 | id: go 19 | 20 | - name: Check out code into the Go module directory 21 | uses: actions/checkout@v1 22 | 23 | - name: Get dependencies 24 | run: | 25 | go get -v -t -d ./... 26 | if [ -f Gopkg.toml ]; then 27 | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh 28 | dep ensure 29 | fi 30 | 31 | - name: Build 32 | run: go build -v . 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.log 2 | **/*.sqlite 3 | .idea/ 4 | ocdb 5 | bin/ 6 | tmp/ 7 | node_modules/ 8 | .sass-cache/ 9 | *-packr.go 10 | public/assets/ 11 | .vscode/ 12 | .grifter/ 13 | .env 14 | **/.DS_Store 15 | *.pid 16 | coverage 17 | coverage.data 18 | .svn 19 | .console_history 20 | .sass-cache/* 21 | .jhw-cache/ 22 | jhw.* 23 | *.sublime* 24 | dist/ 25 | generated/ 26 | .vendor/ 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This is a multi-stage Dockerfile and requires >= Docker 17.05 2 | # https://docs.docker.com/engine/userguide/eng-image/multistage-build/ 3 | FROM quay.io/slukasik/buffalo-builder as builder 4 | 5 | RUN apt-get update && apt-get install -y libxml2-dev zlib1g-dev liblzma-dev libicu-dev 6 | 7 | RUN GO111MODULE=off go get -u -v github.com/gocomply/fedramp/cli/gocomply_fedramp 8 | 9 | RUN mkdir -p $GOPATH/src/github.com/RedHatGov/ocdb 10 | WORKDIR $GOPATH/src/github.com/RedHatGov/ocdb 11 | ENV GO111MODULE on 12 | ENV GOPROXY http://proxy.golang.org 13 | 14 | # this will cache the npm install step, unless package.json changes 15 | ADD package.json . 16 | ADD yarn.lock . 17 | RUN yarn install --no-progress 18 | ADD . . 19 | RUN go get ./... 20 | RUN buffalo build --ldflags '-linkmode external -extldflags "-static -lz -llzma -licuuc -licudata -ldl -lstdc++ -lm"' -o /bin/app 21 | 22 | RUN mkdir -p /var/tmp/ocdb 23 | WORKDIR /var/tmp/ocdb 24 | RUN git clone --depth 1 https://github.com/ComplianceAsCode/oscal ComplianceAsCode.oscal 25 | RUN cd ComplianceAsCode.oscal && PATH=$GOPATH:$PATH make docx 26 | 27 | FROM registry.centos.org/centos:8 28 | 29 | WORKDIR /bin/ 30 | COPY --from=builder /bin/app /go/bin/gocomply_fedramp ./ 31 | 32 | WORKDIR /var/tmp/ 33 | COPY --from=builder /var/tmp/ocdb ocdb 34 | 35 | RUN \ 36 | dnf install -y 'dnf-command(copr)' && \ 37 | dnf copr enable -y openscapmaint/openscap-latest && \ 38 | dnf install --setopt=tsflags=nodocs -y \ 39 | bash git ca-certificates cmake make openscap-scanner python3-pyyaml python3-jinja2 python3 && \ 40 | dnf clean all && \ 41 | chmod --recursive og+w /var/tmp/ocdb 42 | 43 | # Uncomment to run the binary in "production" mode: 44 | # ENV GO_ENV=production 45 | 46 | # Bind the app to 0.0.0.0 so it can be seen from outside the container 47 | ENV ADDR=0.0.0.0 48 | 49 | EXPOSE 3000 50 | 51 | # Uncomment to run the migrations before running the binary: 52 | # CMD /bin/app migrate; /bin/app 53 | CMD exec /bin/app 54 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GO=GO111MODULE=on go 2 | GOBUILD=$(GO) build 3 | 4 | .PHONY: vendor 5 | vendor: 6 | $(GO) mod tidy 7 | $(GO) mod verify 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ATO Pathways 2 | 3 | [![Docker Repository on Quay](https://quay.io/repository/redhatgov/ocdb/status "Docker Repository on Quay")](https://quay.io/repository/redhatgov/ocdb) 4 | 5 | ## Quick Demo 6 | * run demo in container 7 | ``` 8 | podman run -it -p "3000:3000" quay.io/redhatgov/ocdb 9 | ``` 10 | * point your browser to [http://127.0.0.1:3000](http://127.0.0.1:3000) 11 | 12 | ## Developer Setup 13 | 14 | * install golang `dnf install golang libxml2-devel` 15 | * acquire ocdb - `go get -u -v github.com/RedHatGov/ocdb` 16 | * change dir to the source location - `cd ~/go/src/github.com/RedHatGov/ocdb` 17 | * acquire buffallo tool - `go get -v github.com/gobuffalo/buffalo/buffalo` 18 | * optionally consider installing bash completion: https://gobuffalo.io/en/docs/getting-started/integrations 19 | * build front-end pipeline 20 | * install npm `dnf install -y npm` 21 | * install yarn `npm install -g yarn` 22 | * install frontend dependencies `yarn install` 23 | * run server `buffalo dev` 24 | * point your browser to [http://127.0.0.1:3000](http://127.0.0.1:3000) 25 | 26 | ## Developer Links 27 | * [Patternfly 4 documentation](https://patternfly-react.surge.sh/) or [slightly different version](https://www.patternfly.org/v4/documentation/react/overview/release-notes) 28 | 29 | ## Deployment info 30 | 31 | How to pull new version manually in openshift? 32 | 33 | ``` 34 | oc import-image ocdb 35 | ``` 36 | -------------------------------------------------------------------------------- /actions/actions_test.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/packr/v2" 7 | "github.com/gobuffalo/suite" 8 | ) 9 | 10 | type ActionSuite struct { 11 | *suite.Action 12 | } 13 | 14 | func Test_ActionSuite(t *testing.T) { 15 | action, err := suite.NewActionWithFixtures(App(), packr.New("Test_ActionSuite", "../fixtures")) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | as := &ActionSuite{ 21 | Action: action, 22 | } 23 | suite.Run(t, as) 24 | } 25 | -------------------------------------------------------------------------------- /actions/api/admin.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "github.com/RedHatGov/ocdb/actions/jobs" 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | type JobsResource struct { 10 | buffalo.Resource 11 | } 12 | 13 | func (v JobsResource) List(c buffalo.Context) error { 14 | return c.Render(200, r.JSON(jobs.List)) 15 | } 16 | 17 | func ReadinessHandler(c buffalo.Context) error { 18 | for _, j := range jobs.List { 19 | if j.LastSuccess.IsZero() && j.DelayedStart == 0 { 20 | return c.Render(500, r.JSON(fmt.Sprintf("Waiting for unfinished job: %s", j.Name))) 21 | } 22 | } 23 | 24 | return c.Render(200, r.JSON("All jobs succeeded")) 25 | } 26 | -------------------------------------------------------------------------------- /actions/api/certifications.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/pkg/masonry" 5 | "github.com/gobuffalo/buffalo" 6 | ) 7 | 8 | // ComponentsResource show components like defined by opencontrols 9 | type CertificationsResource struct { 10 | buffalo.Resource 11 | } 12 | 13 | // List default implementation. 14 | func (v CertificationsResource) List(c buffalo.Context) error { 15 | ms := masonry.GetInstance() 16 | return c.Render(200, r.JSON(ms.GetAllCertifications())) 17 | } 18 | -------------------------------------------------------------------------------- /actions/api/components.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/RedHatGov/ocdb/pkg/cac_oscal" 7 | "github.com/RedHatGov/ocdb/pkg/masonry" 8 | "github.com/RedHatGov/ocdb/pkg/masonry/stats" 9 | "github.com/gobuffalo/buffalo" 10 | ) 11 | 12 | // ComponentsResource show components like defined by opencontrols 13 | type ComponentsResource struct { 14 | buffalo.Resource 15 | } 16 | 17 | // List default implementation. 18 | func (v ComponentsResource) List(c buffalo.Context) error { 19 | ms := masonry.GetInstance() 20 | return c.Render(200, r.JSON(ms.GetAllComponents())) 21 | } 22 | 23 | // Show default implementation. 24 | func (v ComponentsResource) Show(c buffalo.Context) error { 25 | ms := masonry.GetInstance() 26 | component, found := ms.GetComponent(c.Param("component_id")) 27 | if found { 28 | return c.Render(200, r.JSON(component)) 29 | } 30 | return c.Render(404, r.JSON("Not found")) 31 | } 32 | 33 | // ComponentControlsHandler gives logical human readable view of open control items available. 34 | func ComponentControlsHandler(c buffalo.Context) error { 35 | ms := masonry.GetInstance() 36 | component, found := ms.GetComponent(c.Param("component_id")) 37 | if found { 38 | return c.Render(200, r.JSON(ms.ComponentLogicalView(component))) 39 | } 40 | return c.Render(404, r.JSON("Not found")) 41 | } 42 | 43 | // ComponentStatisticsHandler gives overview of component completion statistics over time 44 | func ComponentStatisticsHandler(c buffalo.Context) error { 45 | stats, found := stats.GetHistoricalStats(c.Param("component_id")) 46 | if found { 47 | return c.Render(200, r.JSON(stats)) 48 | } 49 | return c.Render(404, r.JSON("Not found")) 50 | } 51 | 52 | // ComponentFedrampOscalHandler returns OSCAL documents for given fedramp 53 | func ComponentFedrampOscalHandler(c buffalo.Context) error { 54 | fedrampFormat := strings.ToLower(c.Param("format")) 55 | if fedrampFormat != "xml" && fedrampFormat != "docx" && fedrampFormat != "json" { 56 | return c.Render(404, r.JSON("Unknown oscal format specified "+fedrampFormat+ 57 | ". Please use 'xml', 'json', or 'docx' instead.")) 58 | } 59 | fedrampLevel := c.Param("level") 60 | if fedrampLevel != "High" && fedrampLevel != "Moderate" && fedrampLevel != "Low" { 61 | return c.Render(404, r.JSON("Unknown level specified "+fedrampLevel+ 62 | ". Please use High, Moderate, or Low")) 63 | } 64 | document, err := cac_oscal.FedrampDocument(c.Param("component_id"), fedrampLevel, fedrampFormat) 65 | if err != nil { 66 | return c.Render(404, r.JSON(err.Error())) 67 | } 68 | defer document.Close() 69 | return c.Render(200, 70 | r.Download(c, "FedRAMP-"+fedrampLevel+"-"+c.Param("component_id")+"."+fedrampFormat, 71 | document)) 72 | } 73 | -------------------------------------------------------------------------------- /actions/api/render.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo/render" 5 | ) 6 | 7 | var r = render.New(render.Options{}) 8 | -------------------------------------------------------------------------------- /actions/api/standards.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/pkg/masonry" 5 | "github.com/gobuffalo/buffalo" 6 | ) 7 | 8 | // StandardsResource show standards like defined by opencontrols 9 | type StandardsResource struct { 10 | buffalo.Resource 11 | } 12 | 13 | // List default implementation. 14 | func (v StandardsResource) List(c buffalo.Context) error { 15 | ms := masonry.GetInstance() 16 | return c.Render(200, r.JSON(ms.GetAllStandards())) 17 | } 18 | 19 | // Show default implementation. 20 | func (v StandardsResource) Show(c buffalo.Context) error { 21 | ms := masonry.GetInstance() 22 | standard, found := ms.GetStandard(c.Param("standard_id")) 23 | if found { 24 | return c.Render(200, r.JSON(standard)) 25 | } 26 | return c.Render(404, r.JSON("Not found")) 27 | } 28 | -------------------------------------------------------------------------------- /actions/app.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo" 5 | "github.com/gobuffalo/envy" 6 | paramlogger "github.com/gobuffalo/mw-paramlogger" 7 | 8 | "github.com/RedHatGov/ocdb/actions/api" 9 | "github.com/RedHatGov/ocdb/pkg/cac" 10 | "github.com/RedHatGov/ocdb/pkg/static" 11 | "github.com/RedHatGov/ocdb/pkg/utils" 12 | csrf "github.com/gobuffalo/mw-csrf" 13 | i18n "github.com/gobuffalo/mw-i18n" 14 | "github.com/gobuffalo/packr/v2" 15 | ) 16 | 17 | // ENV is used to help switch settings based on where the 18 | // application is being run. Default is "development". 19 | var ENV = envy.Get("GO_ENV", "development") 20 | var app *buffalo.App 21 | var T *i18n.Translator 22 | 23 | // App is where all routes and middleware for buffalo 24 | // should be defined. This is the nerve center of your 25 | // application. 26 | // 27 | // Routing, middleware, groups, etc... are declared TOP -> DOWN. 28 | // This means if you add a middleware to `app` *after* declaring a 29 | // group, that group will NOT have that new middleware. The same 30 | // is true of resource declarations as well. 31 | // 32 | // It also means that routes are checked in the order they are declared. 33 | // `ServeFiles` is a CATCH-ALL route, so it should always be 34 | // placed last in the route declarations, as it will prevent routes 35 | // declared after it to never be called. 36 | func App() *buffalo.App { 37 | if app == nil { 38 | app = buffalo.New(buffalo.Options{ 39 | Env: ENV, 40 | SessionName: "_ocdb_session", 41 | }) 42 | 43 | // Log request parameters (filters apply). 44 | app.Use(paramlogger.ParameterLogger) 45 | 46 | // Protect against CSRF attacks. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) 47 | // Remove to disable this. 48 | app.Use(csrf.New) 49 | 50 | // Wraps each request in a transaction. 51 | // c.Value("tx").(*pop.Connection) 52 | // Remove to disable this. 53 | //app.Use(popmw.Transaction(models.DB)) 54 | 55 | // Setup and use translations: 56 | app.Use(translations()) 57 | 58 | app.GET("/", PatternflyReactHandler) 59 | app.GET("/ato/{whatever}", PatternflyReactHandler) 60 | app.GET("/ato/{whatever}/{whatever}", PatternflyReactHandler) 61 | app.GET("/ato/{whatever}/{whatever}/{whatever}", PatternflyReactHandler) 62 | 63 | // Support old links from v1 site 64 | app.GET("/product-documents/{whatever}", PatternflyReactHandler) 65 | app.GET("/product-documents/{whatever}/nist-800-53/{whatever}/", PatternflyReactHandler) 66 | 67 | apiV1 := app.Group("/api/v1/") 68 | apiV1.Resource("/standards", api.StandardsResource{&buffalo.BaseResource{}}) 69 | apiV1.Resource("/components", api.ComponentsResource{&buffalo.BaseResource{}}) 70 | apiV1.Resource("/certifications", api.CertificationsResource{&buffalo.BaseResource{}}) 71 | apiV1.GET("/components/{component_id}/controls", api.ComponentControlsHandler) 72 | apiV1.GET("/components/{component_id}/statistics", api.ComponentStatisticsHandler) 73 | apiV1.GET("/components/{component_id}/fedramp/oscal/{format}/{level}", api.ComponentFedrampOscalHandler) 74 | 75 | admin := apiV1.Group("/admin/") 76 | admin.Resource("/jobs", api.JobsResource{&buffalo.BaseResource{}}) 77 | admin.GET("/readiness", api.ReadinessHandler) 78 | 79 | app.ServeFiles("/cac/", cac.BuildFiles()) 80 | app.ServeFiles("/compliance-as-code/scap/", cac.InstalledScapFiles()) 81 | app.ServeFiles("/", static.AssetsBox) // serve files from the public directory 82 | utils.SetLogger(app.Logger) 83 | } 84 | 85 | return app 86 | } 87 | 88 | // translations will load locale files, set up the translator `actions.T`, 89 | // and will return a middleware to use to load the correct locale for each 90 | // request. 91 | // for more information: https://gobuffalo.io/en/docs/localization 92 | func translations() buffalo.MiddlewareFunc { 93 | var err error 94 | if T, err = i18n.New(packr.New("app:locales", "../locales"), "en-US"); err != nil { 95 | app.Stop(err) 96 | } 97 | return T.Middleware() 98 | } 99 | -------------------------------------------------------------------------------- /actions/home_test.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | func (as *ActionSuite) Test_HomeHandler() { 4 | res := as.HTML("/").Get() 5 | 6 | as.Equal(200, res.Code) 7 | as.Contains(res.Body.String(), "OpenControl Database") 8 | } 9 | -------------------------------------------------------------------------------- /actions/jobs/schedule.go: -------------------------------------------------------------------------------- 1 | package jobs 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/pkg/backend/job" 5 | "github.com/RedHatGov/ocdb/pkg/cac" 6 | "github.com/RedHatGov/ocdb/pkg/cac_oscal" 7 | "github.com/RedHatGov/ocdb/pkg/masonry" 8 | "github.com/RedHatGov/ocdb/pkg/masonry/stats" 9 | "github.com/gobuffalo/buffalo/worker" 10 | "time" 11 | ) 12 | 13 | var List = []job.Job{ 14 | job.Job{ 15 | Name: "Open Control Masonry Refresh", 16 | Fn: masonry.Refresh, 17 | Period: time.Hour, 18 | }, 19 | job.Job{ 20 | Name: "ComplianceAsCode Rebuild", 21 | Fn: cac.Refresh, 22 | Period: time.Hour, 23 | }, 24 | job.Job{ 25 | Name: "Open Control Historical Statistics", 26 | Fn: stats.RefreshHistoryStatistics, 27 | Period: time.Hour * 24, 28 | }, 29 | job.Job{ 30 | Name: "Refresh OSCAL resources and Rebuild DOCX templates", 31 | Fn: cac_oscal.Refresh, 32 | Period: time.Hour * 24, 33 | DelayedStart: 10 * time.Minute, 34 | }, 35 | } 36 | 37 | func Init(worker worker.Worker) { 38 | for i, _ := range List { 39 | j := &(List[i]) 40 | j.SetUpIn(worker) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /actions/pattenfly_react.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import "github.com/gobuffalo/buffalo" 4 | 5 | // PatternflyReactHandler is a default handler to serve up 6 | // a home page. 7 | func PatternflyReactHandler(c buffalo.Context) error { 8 | return c.Render(200, r.HTML("index.html")) 9 | } 10 | -------------------------------------------------------------------------------- /actions/render.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/pkg/static" 5 | "github.com/gobuffalo/buffalo/render" 6 | "github.com/gobuffalo/packr/v2" 7 | ) 8 | 9 | var r *render.Engine 10 | 11 | func init() { 12 | r = render.New(render.Options{ 13 | // HTML layout to be used for all HTML requests: 14 | HTMLLayout: "application.plush.html", 15 | 16 | // Box containing all of the templates: 17 | TemplatesBox: packr.New("app:templates", "../templates"), 18 | AssetsBox: static.AssetsBox, 19 | 20 | // Add template helpers here: 21 | Helpers: render.Helpers{ 22 | // for non-bootstrap form helpers uncomment the lines 23 | // below and import "github.com/gobuffalo/helpers/forms" 24 | // forms.FormKey: forms.Form, 25 | // forms.FormForKey: forms.FormFor, 26 | }, 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /actions/workers.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/actions/jobs" 5 | ) 6 | 7 | func init() { 8 | w := App().Worker 9 | jobs.Init(w) 10 | } 11 | -------------------------------------------------------------------------------- /assets/OpenShift_on_Azure_Blueprint-FedRAMP_Moderate.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/OpenShift_on_Azure_Blueprint-FedRAMP_Moderate.docx -------------------------------------------------------------------------------- /assets/css/_buffalo.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | min-width: 320px; 3 | } 4 | 5 | header { 6 | background-color: #62a5ee; 7 | padding: 10px 20px; 8 | box-sizing: border-box; 9 | } 10 | 11 | .logo { 12 | img { 13 | width: 80px; 14 | } 15 | } 16 | 17 | .titles { 18 | h1 { 19 | font-size: 30px; 20 | font-weight: 300; 21 | color: white; 22 | margin-bottom: 13px; 23 | margin-top: 5px; 24 | } 25 | 26 | h2 { 27 | font-weight: 300; 28 | font-size: 18px; 29 | display: inline-block; 30 | margin: 0; 31 | } 32 | 33 | a { 34 | color: white; 35 | text-decoration: underline; 36 | } 37 | 38 | i { 39 | margin-right: 5px; 40 | text-decoration: none; 41 | } 42 | 43 | .documentation { 44 | margin-left: 28px; 45 | } 46 | } 47 | 48 | .subtitle { 49 | color: white; 50 | margin: 0; 51 | padding: 13px 0; 52 | background-color: #2a3543; 53 | margin-bottom: 20px; 54 | 55 | h3 { 56 | font-size: 22px; 57 | font-weight: 400; 58 | margin: 0; 59 | } 60 | } 61 | 62 | table { 63 | font-size: 14px; 64 | 65 | &.table tbody tr td { 66 | border-top: 0; 67 | padding: 10px; 68 | } 69 | } 70 | 71 | .foot { 72 | text-align: right; 73 | color: #c5c5c5; 74 | font-weight: 300; 75 | 76 | a { 77 | color: #8b8b8b; 78 | text-decoration: underline; 79 | } 80 | } 81 | 82 | .centered { 83 | text-align: center; 84 | } 85 | 86 | @media all and (max-width: 770px) { 87 | .titles { 88 | h1 { 89 | font-size: 25px; 90 | margin: 15px 0 5px 0; 91 | } 92 | } 93 | } 94 | 95 | @media all and (max-width: 640px) { 96 | .titles { 97 | h1 { 98 | font-size: 23px; 99 | margin: 15px 0 5px 0; 100 | } 101 | 102 | h2 { 103 | font-size: 15px; 104 | } 105 | 106 | .documentation { 107 | margin-left: 10px; 108 | } 109 | } 110 | } 111 | 112 | @media all and (max-width: 530px) { 113 | .titles { 114 | h1 { 115 | font-size: 20px; 116 | margin: 5px 0; 117 | } 118 | 119 | .documentation { 120 | margin-left: 0px; 121 | margin-top: 5px; 122 | display: block; 123 | } 124 | } 125 | 126 | .logo { 127 | padding: 0; 128 | 129 | img { 130 | width: 100% 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /assets/css/application.scss: -------------------------------------------------------------------------------- 1 | @import "~bootstrap/scss/bootstrap.scss"; 2 | @import "~@fortawesome/fontawesome-free/css/all.min.css"; 3 | 4 | @import "buffalo"; 5 | -------------------------------------------------------------------------------- /assets/images/favicon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/images/favicon-192.png -------------------------------------------------------------------------------- /assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/images/favicon.png -------------------------------------------------------------------------------- /assets/images/markdown/activitystream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/images/markdown/activitystream.png -------------------------------------------------------------------------------- /assets/images/markdown/tower-user-activity-stream-1-creation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/images/markdown/tower-user-activity-stream-1-creation.jpg -------------------------------------------------------------------------------- /assets/images/markdown/tower-user-activity-stream-2-creation-detail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/images/markdown/tower-user-activity-stream-2-creation-detail.jpg -------------------------------------------------------------------------------- /assets/images/markdown/tower-user-activity-stream-3-update.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/images/markdown/tower-user-activity-stream-3-update.jpg -------------------------------------------------------------------------------- /assets/images/markdown/tower-user-activity-stream-4-deletion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/images/markdown/tower-user-activity-stream-4-deletion.jpg -------------------------------------------------------------------------------- /assets/js/application.js: -------------------------------------------------------------------------------- 1 | require("expose-loader?$!expose-loader?jQuery!jquery"); 2 | require("bootstrap/dist/js/bootstrap.bundle.js"); 3 | 4 | $(() => { 5 | 6 | }); 7 | -------------------------------------------------------------------------------- /assets/src/app/AppLayout/About.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | AboutModal, Button, 4 | EmptyStateIcon, 5 | TextContent, Text, TextList, TextListItem } from '@patternfly/react-core'; 6 | import { GithubIcon } from '@patternfly/react-icons'; 7 | import redhatLogo from '@app/assets/images/red-hat-logo.png'; 8 | 9 | 10 | export interface AboutState { 11 | isModalOpen: boolean 12 | }; 13 | 14 | 15 | class SimpleAboutModal extends React.PureComponent<{}, AboutState> { 16 | handleModalToggle() { 17 | } 18 | 19 | constructor(props) { 20 | super(props); 21 | this.state = { 22 | isModalOpen: false 23 | }; 24 | this.handleModalToggle = () => { 25 | this.setState(({ isModalOpen }) => ({ 26 | isModalOpen: !isModalOpen 27 | })); 28 | }; 29 | } 30 | 31 | render() { 32 | const { isModalOpen } = this.state; 33 | 34 | return ( 35 | 36 | 39 | this.handleModalToggle()} 42 | trademark="Copyright © 2019-2020 Red Hat, Inc." 43 | brandImageSrc={redhatLogo} 44 | brandImageAlt="Red Hat Logo" 45 | productName="ATO Pathways" 46 | > 47 | 48 | The Red Hat ATO Pathways microsite provides resources to help accelerate your ATO process. This microsite is a reflection of the open source projects we maintain on GitHub listed below. Please feel free to share and contribute to these projects. All contributions/issues are welcomed! 49 | 50 | ComplianceAsCode 51 | 52 | OpenControl 53 | 54 | OpenControl Database 55 | 56 | 57 | 58 | 59 | 60 | ); 61 | } 62 | } 63 | 64 | export { SimpleAboutModal }; 65 | -------------------------------------------------------------------------------- /assets/src/app/AppLayout/AppLayout.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { SimpleAboutModal } from '@app/AppLayout/About' 3 | import { 4 | Page, 5 | PageHeader, 6 | PageSidebar, 7 | SkipToContent, 8 | PageHeaderTools, 9 | PageHeaderToolsGroup, 10 | PageHeaderToolsItem, 11 | } from '@patternfly/react-core'; 12 | import { InteractiveNavigation } from '@app/AppLayout/Navigation' 13 | // import { ProductSelector } from '@app/AppLayout/ProductSelector' 14 | 15 | interface IAppLayout { 16 | children: React.ReactNode; 17 | } 18 | 19 | const AppLayout: React.FunctionComponent = ({children}) => { 20 | const logoProps = { 21 | href: '/ato/getting_started', 22 | target: '_self' 23 | }; 24 | const [isNavOpen, setIsNavOpen] = React.useState(true); 25 | const [isMobileView, setIsMobileView] = React.useState(true); 26 | const [isNavOpenMobile, setIsNavOpenMobile] = React.useState(false); 27 | const onNavToggleMobile = () => { 28 | setIsNavOpenMobile(!isNavOpenMobile); 29 | }; 30 | const onNavToggle = () => { 31 | setIsNavOpen(!isNavOpen); 32 | } 33 | const onPageResize = (props: { mobileView: boolean; windowSize: number }) => { 34 | setIsMobileView(props.mobileView); 35 | }; 36 | 37 | const pageHeaderTools = ( 38 | 39 | 40 | 41 | {/* */} 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ); 51 | 52 | const Header = ( 53 | 61 | ); 62 | 63 | const Sidebar = ( 64 | } 66 | isNavOpen={isMobileView ? isNavOpenMobile : isNavOpen} theme="dark" /> 67 | ); 68 | const PageSkipToContent = ( 69 | 70 | Skip to Content 71 | 72 | ); 73 | return ( 74 | 80 | {children} 81 | 82 | ); 83 | } 84 | 85 | export { AppLayout }; 86 | -------------------------------------------------------------------------------- /assets/src/app/AppLayout/ProductSelector.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import * as Api from '@app/lib/api' 3 | import { ContextSelector, ContextSelectorItem } from '@patternfly/react-core'; 4 | import { withRouter } from 'react-router-dom'; 5 | 6 | interface ProductSelection { 7 | id: string, 8 | name: string, 9 | } 10 | 11 | interface ProductSelectorState { 12 | visible: boolean; 13 | isOpen: boolean; 14 | selected?: string; 15 | selectedId?: string; 16 | searchValue: string; 17 | filteredItems: ProductSelection[]; 18 | items: ProductSelection[]; 19 | } 20 | 21 | export function GetActiveProductIdFromUrl() { 22 | if (window.location.pathname.startsWith('/ato/products/')) 23 | return window.location.pathname.replace(/\/ato\/products\/([\w-]+).*/, '$1'); 24 | return undefined; 25 | } 26 | 27 | export function GetProductParamsFromUrl() { 28 | if (window.location.pathname.startsWith('/ato/products/')) { 29 | return window.location.pathname.replace(/\/ato\/products\/[\w-]+(\/.*)/, '$1') + window.location.search + window.location.hash; 30 | } 31 | return undefined; 32 | } 33 | 34 | class BaseProductSelector extends React.PureComponent { 35 | static visible() { 36 | return window.location.pathname.startsWith('/ato/products') 37 | } 38 | static getDerivedStateFromProps(props, state) { 39 | state.visible = BaseProductSelector.visible(); 40 | const newProductId = GetActiveProductIdFromUrl(); 41 | if (newProductId != state.selectedId) 42 | if (!newProductId || newProductId == 'select') { 43 | state.selectedId = newProductId 44 | state.selected = undefined 45 | } else if (state.items.length > 0) { 46 | state.selectedId = newProductId; 47 | state.selected = state.items.filter((function(p, i) { return p.id === newProductId; }))[0].name; 48 | } 49 | return state; 50 | } 51 | 52 | finalizeSelector(componets) { 53 | const items = componets.map((function(component, idx) { 54 | return { id: component['key'], name: component['name']}; 55 | })) 56 | this.setState({items: items, filteredItems: items, searchValue: ''}); 57 | }; 58 | 59 | onToggle(event, isOpen) { 60 | this.setState({ 61 | isOpen 62 | }); 63 | }; 64 | 65 | onSelect(event, value) { 66 | var productId = this.state.selectedId; 67 | if (value != this.state.selected) { 68 | const product = this.state.items.find((function(p, i) { return p.name === value })); 69 | productId = (product == undefined) ? '' : product.id; 70 | this.props.history.push('/ato/products/' + productId + GetProductParamsFromUrl()); 71 | } 72 | 73 | this.setState({ 74 | selected: value, 75 | selectedId: productId, 76 | isOpen: !this.state.isOpen 77 | }); 78 | }; 79 | 80 | filterItems(searchValue) { 81 | return searchValue === '' 82 | ? this.state.items 83 | : this.state.items.filter(item => item.name.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1); 84 | } 85 | 86 | onSearchInputChange(searchValue) { 87 | this.setState({ searchValue, filteredItems: this.filterItems(searchValue) }); 88 | }; 89 | 90 | onSearchButtonClick(event) { 91 | this.setState({ filteredItems: this.filterItems(this.state.searchValue) }); 92 | }; 93 | 94 | constructor(props) { 95 | super(props); 96 | this.state = { 97 | visible: false, 98 | isOpen: false, 99 | selected: undefined, 100 | searchValue: '', 101 | filteredItems: [], 102 | items: [] 103 | }; 104 | Api.components().then(data => this.finalizeSelector(data)); 105 | this.onToggle = this.onToggle.bind(this); 106 | this.onSelect = this.onSelect.bind(this); 107 | this.onSearchInputChange = this.onSearchInputChange.bind(this); 108 | this.onSearchButtonClick = this.onSearchButtonClick.bind(this); 109 | } 110 | 111 | render() { 112 | const { isOpen, selected, searchValue, filteredItems, visible } = this.state; 113 | if (!visible) { 114 | return '' 115 | } 116 | 117 | return ( 118 | 128 | {filteredItems.map((item, index) => ( 129 | {item.name} 130 | ))} 131 | 132 | ); 133 | } 134 | } 135 | 136 | export const ProductSelector = withRouter(BaseProductSelector); 137 | -------------------------------------------------------------------------------- /assets/src/app/AppLayout/Routes.tsx: -------------------------------------------------------------------------------- 1 | abstract class BaseRoute { 2 | abstract isGroup(): boolean; 3 | constructor(public label: string) { this.label = label; } 4 | } 5 | 6 | abstract class BaseRouteLink extends BaseRoute { 7 | isGroup(): boolean { return false }; 8 | abstract routesTo(productId?: string): string; 9 | abstract matches(url: string): boolean; 10 | abstract hasChilds(): boolean; 11 | } 12 | 13 | class BasicRoute extends BaseRouteLink { 14 | constructor(label: string, public to: string) { 15 | super(label); 16 | this.to = to; 17 | } 18 | routesTo(_unused?:string): string { 19 | return this.to; 20 | } 21 | matches(url: string): boolean { 22 | return this.to == url 23 | } 24 | hasChilds(): boolean { return false; } 25 | } 26 | 27 | class ProductRoute extends BaseRouteLink { 28 | constructor(label: string, public productTo: string, public subRoutes?: ProductRoute[]) { 29 | super(label); 30 | this.productTo = productTo; 31 | this.subRoutes = subRoutes; 32 | } 33 | routesTo(productId?:string): string { 34 | if (productId) { 35 | return this.productTo.replace('select', productId) 36 | } else { 37 | return this.productTo 38 | } 39 | } 40 | matches(url: string): boolean { 41 | const matcher = this.productTo.replace('select', '[\\w-]+'); 42 | return url.search(matcher) != -1; 43 | } 44 | hasChilds(): boolean { return this.subRoutes !== undefined } 45 | } 46 | 47 | class RouterGroup extends BaseRoute { 48 | isGroup(): boolean { return true }; 49 | constructor(label: string, public routes: BasicRoute[]) { 50 | super(label); 51 | this.routes = routes; 52 | } 53 | } 54 | 55 | export { BaseRoute, BaseRouteLink, BasicRoute, ProductRoute, RouterGroup } 56 | -------------------------------------------------------------------------------- /assets/src/app/NotFound/NotFound.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { NavLink } from 'react-router-dom'; 3 | import { Alert, PageSection } from '@patternfly/react-core'; 4 | 5 | const NotFound: React.FunctionComponent = () => { 6 | return ( 7 | 8 |
9 | Take me home 10 |
11 | ); 12 | } 13 | 14 | export { NotFound }; 15 | -------------------------------------------------------------------------------- /assets/src/app/__snapshots__/app.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`App tests should render default App component 1`] = ` 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | `; 14 | -------------------------------------------------------------------------------- /assets/src/app/app.css: -------------------------------------------------------------------------------- 1 | html, body, #root { 2 | height: 100%; 3 | } 4 | 5 | .pf-l-flex.rmf { 6 | align-items: unset; 7 | --pf-l-flex--AlignItems: unset; 8 | margin-top: auto; 9 | } 10 | 11 | /* Use this to vertically center content in a div. This is what is on the 12 | Getting Started page for the list */ 13 | .vertical-center { 14 | margin: 0; 15 | position: relative; 16 | top: 50%; 17 | -ms-transform: translateY(-50%); 18 | transform: translateY(-50%); 19 | } 20 | 21 | /* Fix color for Nav Section Titles */ 22 | .pf-c-nav__section-title { 23 | border-bottom: var(--pf-c-nav__section-title--BorderBottomWidth) solid #ffffff; 24 | color: #c3bfbf; 25 | } 26 | 27 | .navitm { 28 | --pf-c-nav__link--before--BorderColor: transparent; 29 | } 30 | 31 | .prod-card { 32 | height: 15em; 33 | } 34 | 35 | .prod-gallery { 36 | --pf-l-gallery--GridTemplateColumns: repeat(auto-fill, minmax(256px, 1fr)); 37 | } 38 | 39 | /* Add more space to the grid gutter */ 40 | .pf-l-gallery.pf-m-gutter.prod-gallery { 41 | grid-gap: 1.5rem; 42 | } 43 | 44 | a.prod-navlink { 45 | color: #151515; 46 | text-decoration: none; 47 | } 48 | 49 | /* Since using a CardTitle causes spacing issues with footer, the solution is to 50 | just use CardBody for the prod title - then add some font boldness to look just 51 | like CardTitle */ 52 | .prod-cardbody { 53 | font-weight: bold; 54 | } 55 | 56 | .nav-grouplink { 57 | font-size: var(--pf-global--FontSize--md); 58 | } 59 | 60 | /* Product Page Header config */ 61 | .pf-c-page__header.product-header { 62 | color: black; 63 | background-color: var(--pf-c-page__main-section--m-light--BackgroundColor); 64 | } 65 | 66 | h1.pf-c-page__header-brand-link { 67 | font-size: x-large; 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /assets/src/app/app.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { App } from '@app/index'; 3 | import { mount, shallow } from 'enzyme'; 4 | import { Button } from '@patternfly/react-core'; 5 | 6 | describe('App tests', () => { 7 | test('should render default App component', () => { 8 | const view = shallow(); 9 | expect(view).toMatchSnapshot(); 10 | }); 11 | 12 | it('should render a nav-toggle button', () => { 13 | const wrapper = mount(); 14 | const button = wrapper.find(Button); 15 | expect(button.exists()).toBe(true); 16 | }); 17 | 18 | it('should hide the sidebar when clicking the nav-toggle button', () => { 19 | const wrapper = mount(); 20 | const button = wrapper.find('#nav-toggle').hostNodes(); 21 | expect(wrapper.find('#page-sidebar').hasClass('pf-m-expanded')); 22 | button.simulate('click'); 23 | expect(wrapper.find('#page-sidebar').hasClass('pf-m-collapsed')); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /assets/src/app/assets/images/RMF-steps-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/RMF-steps-all.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/atopathways.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/atopathways.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/nist-logo-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/nist-logo-2x.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/red-hat-logo-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/red-hat-logo-a.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/red-hat-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/red-hat-logo.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-acm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-acm.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-coreos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-coreos.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-hat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-hat.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-openshift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-openshift.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-openstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-openstack.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-rhel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-rhel.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-rhel8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-rhel8.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-tower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-tower.png -------------------------------------------------------------------------------- /assets/src/app/assets/images/rh-virtualization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/assets/src/app/assets/images/rh-virtualization.png -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/ansible-tower/Overview.md: -------------------------------------------------------------------------------- 1 | ## Common Criteria 2 | Ansible Tower has not undergone Common Criteria certification. A future certification 3 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) is being considered. 4 | 5 | To help Red Hat track demand for a Common Criteria certification of Ansible Tower, please open a customer support case requesting a certification. 6 | 7 | ## FIPS 140-2 8 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 9 | 10 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic 11 | subsystems or components, such as OpenSSL and OpenSSH, are validated. 12 | 13 | When Ansible Tower runs on Red Hat Enterprise Linux 7.x, the following FIPS 140-2 validations 14 | are retained: 15 | 16 | | Product | Component | Version | NIST Certificate | Status | Sunset/Expiration? | 17 | |:--------|:----------|:-------:|:----------------:|:------:|:------------------:| 18 | | Red Hat Enterprise Linux 7.x | OpenSSL | 5.0 | [#3016](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3016) | ACTIVE | 9/14/2022 | 19 | | Red Hat Enterprise Linux 7.x | OpenSSH Client | 5.0 | [#3067](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3067) | ACTIVE | 11/26/2022 | 20 | | Red Hat Enterprise Linux 7.x | OpenSSH Server | 5.0 | [#3063](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3063) | ACTIVE | 11/13/2022 | 21 | | Red Hat Enterprise Linux 7.x | Libreswan | 5.0 | [#3083](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3083) | ACTIVE | 12/18/2022 | 22 | | Red Hat Enterprise Linux 7.x | GnuTLS | 5.0 | [#3012](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3012) | ACTIVE | 9/7/2022 | 23 | | Red Hat Enterprise Linux 7.x | libgcrypt | 5.0 | [#2657](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/2657) | ACTIVE | 6/12/2021 | 24 | | Red Hat Enterprise Linux 7.x | NSS | 5.0 | [#3070](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3070) | ACTIVE | 2/7/2023 | 25 | 26 | #### Known Issues with FIPS 140-2 Enablement 27 | As of Ansible Tower version 3.4, Tower can run on systems where FIPS mode is enabled, with some limitations. Refer to [the release notes](https://docs.ansible.com/ansible-tower/3.4.0/html/installandreference/install_notes_reqs.html#installing-tower-on-systems-with-fips-mode-enabled) for more information. 28 | 29 | ### USGv6 / IPv6 30 | Ansible Tower does not have any US Government IPv6 certifications. 31 | 32 | ### Section 508 / VPAT 33 | Direct link to Ansible Tower 3.x Section 508 VPAT and WCAG documentation: 34 | [https://www.ansible.com/hubfs/government/Ansible_Tower_Section_508_VPAT.pdf?hsLang=en-us](https://www.ansible.com/hubfs/government/Ansible_Tower_Section_508_VPAT.pdf?hsLang=en-us). 35 | 36 | ### Configuration Guides 37 | A NIST National Checklist for Ansible Tower is currently being developed. Contact your Red Hat 38 | representative for pre-release access! 39 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/ansible-tower/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for Ansible Tower is currently not available. 4 | 5 | ### Download released content available at NIST NVD 6 | * [FedRAMP Low for Red Hat Ansible Tower 3.2.x v1 Checklist](https://nvd.nist.gov/ncp/checklist/863) 7 | 8 | ### Deprecated STIG draft for Ansible Tower on RHEL7 9 | Deprecated STIG content for Ansible Tower on RHEL7 can be found in 10 | [ComplianceAsCode project](https://github.com/ComplianceAsCode/content) 11 | release [0.1.52](https://github.com/ComplianceAsCode/content/releases/tag/v0.1.52). 12 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/coreos-4/Overview.md: -------------------------------------------------------------------------------- 1 | ## Common Criteria 2 | CoreOS v4.x has not undergone Common Criteria certification. A future certification 3 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) is being considered. 4 | 5 | To help Red Hat track demand for a Common Criteria certification of CoreOS v4.x, please open a customer support case requesting a certification. 6 | 7 | ## FIPS 140-2 8 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 9 | 10 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic 11 | subsystems or components, such as OpenSSL and OpenSSH, are validated. 12 | 13 | CoreOS 4.3+ provides FIPS validated cryptographc functions to Red Hat Openshift Container Platform via FIPS validated RHEL libraries when [properly configured](https://docs.openshift.com/container-platform/4.3/installing/installing-fips.html) before initial cluster boot. FIPS 140-2 validated crytpographic functions are used by critical portions of Openshift which store data, including the etcd database when encrypted and containerized workloads when configured to use the CRI-O container runtimes. 14 | 15 | ### USGv6 / IPv6 16 | CoreOS v4.x does not have any US Government IPv6 certifications. 17 | 18 | ### Section 508 / VPAT 19 | CoreOS 4.x does not currently have a VPAT document. CoreOS is designed to provide operating system services for Openshift, which provides the primary user interfaces. Refer to the corresponding [Openshift overview and VPAT](https://atopathways.redhatgov.io/ato/products/openshift-container-platform-4/Overview). 20 | 21 | ### Configuration Guides 22 | A NIST National Checklist for CoreOS v4.x is currently being developed. 23 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/coreos-4/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for Red Hat Enterprise Linux CoreOS is being developed under [ComplianceAsCode project](https://github.com/ComplianceAsCode/content). Configuration compliance with the given SCAP content can be assessed automatically using [OpenSCAP tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/scanning-the-system-for-security-compliance-and-vulnerabilities_security-hardening). 4 | 5 | Introductionary material for scanning RHEL CoreOS 4 nodes from inside the OpenShift 4 cluster is available at [OpenShift Blog](https://www.openshift.com/blog/rhel-coreos-compliance-scanning-in-openshift-4) 6 | 7 | Enterprising users are invited to early use of [compliance-operator](https://github.com/openshift/compliance-operator). Compliance-operator, when loading inside OpenShift cluster can be used to assess OpenShift nodes from inside the cluster. Compliance-operator is also able to remediate configuration setting using Ignition script language using Machine Config Operator directly. 8 | 9 | ### Latest Greatest Documents 10 | This is a *draft* content. This profile reflects U.S. Government consensus content and is developed through the OpenSCAP/ComplianceAsCode initiative, championed by the National Security Agency. Latest version of the documents can be obtained from upstream project or under following links. 11 | 12 | Available profiles: 13 | * Australian Cyber Security Centre (ACSC) Essential Eight: [HTML](/cac/guides/ssg-rhcos4-guide-e8.html), [Ignition](/cac/rhcos4/ignition-fixes.xml) 14 | * NIST 800-53 Moderate-Impact Baseline for Red Hat Enterprise Linux CoreOS: [HTML](/cac/guides/ssg-rhcos4-guide-moderate.html), [Ignition](/cac/rhcos4/ignition-fixes.xml) 15 | * NIST National Checklist for Red Hat Enterprise Linux CoreOS: [HTML](/cac/guides/ssg-rhcos4-guide-ncp.html), [Ignition](/cac/rhcos4/ignition-fixes.xml) 16 | 17 | SCAP content: 18 | * All in one DataStream: [SCAP 1.3](/cac/ssg-rhcos4-ds.xml), [SCAP 1.2](/cac/ssg-rhcos4-ds-1.2.xml) 19 | * Checklist: [XCCDF 1.2](/cac/ssg-rhcos4-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-rhcos4-xccdf.xml) 20 | * Assessment Details: [OVAL](/cac/ssg-rhcos4-oval.xml) 21 | * Questionnaire: [OCIL](/cac/ssg-rhcos4-ocil.xml) 22 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/identity-management/Overview.md: -------------------------------------------------------------------------------- 1 | ## Configuration Guides 2 | A NIST National Checklist for Red Hat Identity Management is currently being developed. 3 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/insights/Overview.md: -------------------------------------------------------------------------------- 1 | ## Configuration Guides 2 | A NIST National Checklist for Red Hat Insights is currently being developed. 3 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/openshift-container-platform-3/Overview.md: -------------------------------------------------------------------------------- 1 | import { OutlinedFileWordIcon } from '@patternfly/react-icons' 2 | 3 | 4 | ## Common Criteria 5 | OpenShift Container Platform 3.x has not undergone Common Criteria certification. A future certification 6 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) is being considered. 7 | 8 | To help Red Hat track demand for a Common Criteria certification of OpenShift Container Platform 3.x, please open a 9 | customer support case requesting an evaluation. 10 | 11 | ## FIPS 140-2 12 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 13 | 14 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic 15 | subsystems or components, such as OpenSSL and OpenSSH, are validated. 16 | 17 | When OpenShift Container Platform 3.x runs on Red Hat Enterprise Linux 7.x, the following FIPS 140-2 validations 18 | are retained: 19 | 20 | | Product | Component | Version | NIST Certificate | Status | Sunset/Expiration? | 21 | |:--------|:----------|:-------:|:----------------:|:------:|:------------------:| 22 | | Red Hat Enterprise Linux 7.x | OpenSSL | 5.0 | [#3016](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3016) | ACTIVE | 9/14/2022 | 23 | | Red Hat Enterprise Linux 7.x | OpenSSH Client | 5.0 | [#3067](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3067) | ACTIVE | 11/26/2022 | 24 | | Red Hat Enterprise Linux 7.x | OpenSSH Server | 5.0 | [#3063](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3063) | ACTIVE | 11/13/2022 | 25 | | Red Hat Enterprise Linux 7.x | Libreswan | 5.0 | [#3083](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3083) | ACTIVE | 12/18/2022 | 26 | | Red Hat Enterprise Linux 7.x | GnuTLS | 5.0 | [#3012](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3012) | ACTIVE | 9/7/2022 | 27 | | Red Hat Enterprise Linux 7.x | libgcrypt | 5.0 | [#2657](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/2657) | ACTIVE | 6/12/2021 | 28 | | Red Hat Enterprise Linux 7.x | NSS | 5.0 | [#3070](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3070) | ACTIVE | 2/7/2023 | 29 | 30 | #### Known Issues with FIPS 140-2 Enablement 31 | In OpenShift 3.10 and earlier, OpenShift utilized Golang-provided cryptographic libraries which have not undergone FIPS 140 validations. A potential mitigation was to use [Opportunistic IPSec](https://docs.openshift.com/container-platform/3.10/admin_guide/ipsec.html) which encapsulates all traffic in FIPS 140-2 validated OpenSSL tunnels (meeting the requirement for encryption in transit). Note this would encapsulate all traffic internal to the OpenShift environment, and would not protect external ingress/egress of traffic to the OpenShift environment itself. 32 | 33 | OpenShift 3.11 and later was patched to use OpenSSL libraries provided by Red Hat Enterprise Linux. 34 | 35 | ## USGv6 / IPv6 36 | OpenShift Container Platform 3.x does not have any US Government IPv6 certifications. 37 | 38 | ## Section 508 / VPAT 39 | Coming soon. 40 | 41 | ## Configuration Guides 42 | A NIST National Checklist for OpenShift Container Platform 3.x is currently being developed. Contact your Red Hat 43 | representative for pre-release access! 44 | 45 | ## Risk Register 46 | To assist with risk management decisions, a listing of known OpenShift limitations against NIST 800-53 rev4 controls is provided below. Limitations are categorized as high/medium/low severity in alignment with DISA's Vulnerability Severity Category Code Definitions: 47 | 48 | | Severity Definition | DISA Category Code Guidelines | 49 | |:---------------:|:------------------------------| 50 | | HIGH (CAT I) | Any vulnerability, the exploitation of which will directly and immediately result in loss of Confidentiality, Availability, or Integrity.| 51 | | MEDIUM (CAT II) | Any vulnerability, the exploitation of which has a potential to result in loss of Confidentiality, Availability, or Integrity.| 52 | | LOW (CAT III) | Any vulnerability, the existence of which degrades measures to protect against loss of Confidentiality, Availability, or Integrity.| 53 | 54 | The following are known limitations of OpenShift 3.x's ability to meet NIST 800-53 rev4 technical controls: 55 | 56 | | NIST 800-53 Control | Risk Determination | Description/Rationale | 57 | |:-------------------:|:------------------:|:---------------------------| 58 | | AC-7(b) | LOW | AC-7(b) requires that, upon exceeding consecutive failed logon attempt limits, the information system delays the next logon prompt by a selected amount of time. This capability is not present in OpenShift 3.x nor is it planned. The risk of Denial of Service attacks is mitigated through network settings, such as rate limiting through firewall configuration settings. If this capability is meaningful for your deployment, please open a feature request through your Red Hat account team.| 59 | 60 | 61 | ## OpenShift Container Platform 3.x on Azure for Government 62 | Using the FedRAMP-provided System Security Plan for Moderate impact systems, Red Hat and Microsoft collaborated on the release of an Azure Blueprint. The document is designed to identify which controls are inherited from Azure's FedRAMP accreditation, which are satisfied through native Red Hat OpenShift Container Platform capabilities, and which security controls are the responsibility of the system operator (procedural controls). 63 | 64 | | | FedRAMP Moderate | 65 | |:-------------------:|:------------------:| 66 | |OpenShift Container Platform 3.x on Azure for Government|[ .docx template](/assets/OpenShift_on_Azure_Blueprint-FedRAMP_Moderate.docx)| 67 | 68 | 69 | Other resources for deploying OpenShift on Azure include: 70 | - [Deploying Red Hat OpenShift Container Platform on Microsoft Azure](https://access.redhat.com/articles/3030691) reference architecture 71 | - [Deploying and Managing OpenShift on Azure](https://github.com/openshift/openshift-ansible-contrib/tree/master/reference-architecture/azure-ansible) Ansible Playbooks 72 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/openshift-container-platform-3/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for OpenShift Container Platform 3 has been last shipped in [Release 0.1.52](https://github.com/ComplianceAsCode/content/releases/tag/v0.1.52) of [ComplianceAsCode project](https://github.com/ComplianceAsCode/content) 4 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/openshift-container-platform-4/Overview.md: -------------------------------------------------------------------------------- 1 | ## Common Criteria 2 | OpenShift Container Platform 4 has not undergone Common Criteria certification. A future certification 3 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) 4 | is being considered. 5 | 6 | To help Red Hat track demand for a Common Criteria certification of OpenShift Container Platform v4.x, 7 | please [open a customer support case](https://access.redhat.com/support/cases/#/case/new) requesting 8 | a certification. 9 | 10 | ## FIPS 140-2 11 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools 12 | implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's 13 | [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 14 | 15 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic subsystems 16 | or components, such as OpenSSL and OpenSSH, are validated. 17 | 18 | Currently, OpenShift Container Platform 4.x does not have any FIPS validations and does not use FIPS 19 | validated cryptography. Those features are roadmapped for a future OpenShift Container Platform 4.x 20 | release. [Product Documentation](https://docs.openshift.com/container-platform/4.4/installing/installing-fips.html) 21 | can be consulted to review the latest developments on this front. 22 | 23 | ### USGv6 / IPv6 24 | OpenShift Container Platform v4.x does not have any US Government IPv6 certifications. 25 | 26 | ### Section 508 / VPAT 27 | [Red Hat Accessibility Conformance Report](https://access.redhat.com/sites/default/files/attachments/openshift-4-vpat.pdf) is available as of July 10, 2020. Full listings of VPAT guides can be seen at [Red Hat Knowledge Base](https://access.redhat.com/articles/2918071). 28 | 29 | ### Configuration Guides 30 | A NIST National Checklist for OpenShift Container Platform v4.x is currently being developed. 31 | 32 | ## NIST 800-53 33 | NIST 800-53 control responses are available to the general public in [interactive form](/ato/products/openshift-container-platform-4/NIST-800-53). 34 | For immediate evaluation of certification responses progress review [NIST-800-53 visuals](/ato/products/openshift-container-platform-4/Charts?tab=0) 35 | 36 | ## SCAP 37 | SCAP content for automated assessment of OpenShift Container platform is developed in open source under 38 | [ComplianceAsCode](https://github.com/ComplianceAsCode/content) upstream project. To download the latest 39 | greatest bits follow up to the [SCAP Download Page](/ato/products/openshift-container-platform-4/SCAP). 40 | 41 | ## Red Hat CoreOS 42 | [Red Hat CoreOS ATO](http://atopathways.redhatgov.io/ato/products/coreos-4/Overview) is tracked on separate 43 | page. 44 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/openshift-container-platform-4/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for OpenShift Container Platform 4 is being developed under [ComplianceAsCode project](https://github.com/ComplianceAsCode/content). Configuration compliance with the given SCAP content can be assessed automatically using [OpenSCAP tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/scanning-the-system-for-security-compliance-and-vulnerabilities_security-hardening). 4 | 5 | ### Open Computing Information Security Profile 6 | Available downloads: 7 | * Implementation Guide 8 | * Australian Cyber Security Centre (ACSC) Essential Eight [HTML](/cac/guides/ssg-ocp4-guide-e8.html) 9 | * CIS Red Hat OpenShift Container Platform 4 Benchmark [HTML](/cac/guides/ssg-ocp4-guide-cis.html) 10 | * NIST 800-53 Moderate-Impact Baseline for Red Hat OpenShift [HTML](/cac/guides/ssg-ocp4-guide-moderate.html) 11 | * NIST National Checklist for Red Hat OpenShift Container Platform [HTML](/cac/guides/ssg-ocp4-guide-ncp.html) 12 | * SCAP content 13 | * All in one DataStream: [SCAP 1.3](/cac/ssg-ocp4-ds.xml), [SCAP 1.2](/cac/ssg-ocp4-ds-1.2.xml) 14 | * Checklist: [XCCDF 1.2](/cac/ssg-ocp4-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-ocp4-xccdf.xml) 15 | * Assessment Details: [OVAL](/cac/ssg-ocp4-oval.xml) 16 | * Questionnaire: [OCIL](/cac/ssg-ocp4-ocil.xml) 17 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/openshift-dedicated/Overview.md: -------------------------------------------------------------------------------- 1 | ## Configuration Guides 2 | A NIST National Checklist for Red Hat Openshift Dedicated is currently being developed. 3 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/openstack-platform-13/Overview.md: -------------------------------------------------------------------------------- 1 | ## Common Criteria 2 | OpenStack Platform 13 has not undergone Common Criteria certification. A future certification 3 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) is being considered. 4 | 5 | To help Red Hat track demand for a Common Criteria certification of OpenStack Platform 13, please open a 6 | customer support case requesting an evaluation. 7 | 8 | ## FIPS 140-2 9 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 10 | 11 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic 12 | subsystems or components, such as OpenSSL and OpenSSH, are validated. 13 | 14 | When OpenStack Platform 13 runs on Red Hat Enterprise Linux 7.x, the following FIPS 140-2 validations 15 | are retained: 16 | 17 | | Product | Component | Version | NIST Certificate | Status | Sunset/Expiration? | 18 | |:--------|:----------|:-------:|:----------------:|:------:|:------------------:| 19 | | Red Hat Enterprise Linux 7.x | OpenSSL | 5.0 | [#3016](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3016) | ACTIVE | 9/14/2022 | 20 | | Red Hat Enterprise Linux 7.x | OpenSSH Client | 5.0 | [#3067](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3067) | ACTIVE | 11/26/2022 | 21 | | Red Hat Enterprise Linux 7.x | OpenSSH Server | 5.0 | [#3063](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3063) | ACTIVE | 11/13/2022 | 22 | | Red Hat Enterprise Linux 7.x | Libreswan | 5.0 | [#3083](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3083) | ACTIVE | 12/18/2022 | 23 | | Red Hat Enterprise Linux 7.x | GnuTLS | 5.0 | [#3012](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3012) | ACTIVE | 9/7/2022 | 24 | | Red Hat Enterprise Linux 7.x | libgcrypt | 5.0 | [#2657](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/2657) | ACTIVE | 6/12/2021 | 25 | | Red Hat Enterprise Linux 7.x | NSS | 5.0 | [#3070](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3070) | ACTIVE | 2/7/2023 | 26 | 27 | #### Known Issues with FIPS 140-2 Enablement 28 | Coming soon. 29 | 30 | ### USGv6 / IPv6 31 | OpenStack Platform 13 does not have any US Government IPv6 certifications. 32 | 33 | ### Section 508 / VPAT 34 | Coming soon. 35 | 36 | ### Configuration Guides 37 | A NIST National Checklist for OpenStack Platform 13 is currently being developed. Contact your Red Hat 38 | representative for pre-release access! 39 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/openstack-platform-13/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for Red Hat OpenStack Platform is being developed under [ComplianceAsCode project](https://github.com/ComplianceAsCode/content). Configuration compliance with the given SCAP content can be assessed automatically using [OpenSCAP tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/scanning-the-system-for-security-compliance-and-vulnerabilities_security-hardening). 4 | 5 | ### Download released content available at NIST NVD 6 | * [FedRAMP Moderate for Red Hat OpenStack Platform 13 Checklist Details](https://nvd.nist.gov/ncp/checklist/864) 7 | 8 | ### STIG Latest greatest documents 9 | This is a *draft* profile for STIG. This profile is being developed under the DoD consensus model to become a STIG in coordination with DISA FSO. Latest version of the documents can be obtained from upstream project or under following links. 10 | 11 | Available downloads: 12 | * Implementation Guide: [HTML](/cac/guides/ssg-rhosp13-guide-stig.html) 13 | * SCAP content 14 | * All in one DataStream: [SCAP 1.3](/cac/ssg-rhosp13-ds.xml), [SCAP 1.2](/cac/ssg-rhosp13-ds-1.2.xml) 15 | * Checklist: [XCCDF 1.2](/cac/ssg-rhosp13-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-rhosp13-xccdf.xml) 16 | * Assessment Details: [OVAL](/cac/ssg-rhosp13-oval.xml) 17 | * Questionnaires: [OCIL](/cac/ssg-rhosp13-ocil.xml) 18 | * All in one remediation script: [Ansible Playbook](/cac/ansible/rhosp13-playbook-stig.yml), [Bash](/cac/bash/rhosp13-script-stig.sh) 19 | 20 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/rhacm/Overview.md: -------------------------------------------------------------------------------- 1 | ## Common Criteria 2 | Red Hat Advanced Cluster Management for Kubernetes has not undergone Common Criteria certification. A future certification 3 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) 4 | is being considered. 5 | 6 | To help Red Hat track demand for a Common Criteria certification of Red Hat Advanced Cluster Management for Kubernetes v2.x, 7 | please [open a customer support case](https://access.redhat.com/support/cases/#/case/new) requesting 8 | a certification. 9 | 10 | ## FIPS 140-2 11 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools 12 | implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's 13 | [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 14 | 15 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic subsystems 16 | or components, such as OpenSSL and OpenSSH, are validated. 17 | 18 | Currently, Red Hat Advanced Cluster Management for Kubernetes does not have any FIPS validations and does not 19 | use FIPS validated cryptography. Those features are road-mapped for future releases. 20 | 21 | ### USGv6 / IPv6 22 | Red Hat Advanced Cluster Management for Kubernetes does not have any US Government IPv6 certifications. 23 | 24 | ### Section 508 / VPAT 25 | [Red Hat Accessibility Conformance Report](https://access.redhat.com/sites/default/files/attachments/section508-vpat-rhacm-2.0.pdf) 26 | is available as of 5th August 2020. Full listings of VPAT guides can be seen at 27 | [Red Hat Knowledge Base](https://access.redhat.com/articles/2918071). 28 | 29 | ### Configuration Guides 30 | A NIST National Checklist for Red Hat Advanced Cluster Management for Kubernetes is currently being developed. 31 | 32 | ## NIST 800-53 33 | NIST 800-53 control responses are available to the general public in [interactive form](/ato/products/rhacm/NIST-800-53). 34 | For immediate evaluation of certification responses progress, review [NIST-800-53 visuals](/ato/products/rhacs/Charts?tab=0). 35 | 36 | ## SCAP 37 | SCAP content for automated assessment of Red Hat Advanced Cluster Management is not available at the moment. 38 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/rhel-7/Overview.md: -------------------------------------------------------------------------------- 1 | Continue to overview of [SCAP Resources available](/ato/products/rhel-7/SCAP). 2 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/rhel-7/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for Red Hat Enterprise Linux 7 is being developed under [ComplianceAsCode project](https://github.com/ComplianceAsCode/content). This content is periodically shipped within Red Hat Enterprise Linux 7, scap-security-guide package. Configuration compliance with the given SCAP content can be assessed automatically using [OpenSCAP tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/configuration-compliance-scanning_scanning-the-system-for-configuration-compliance-and-vulnerabilities). 4 | 5 | ### Released content available at NIST NVD 6 | * [NIST National Checklist for Red Hat Enterprise Linux 7.x content](https://nvd.nist.gov/ncp/checklist/811) 7 | 8 | ### Latest greatest documents 9 | Available Profiles: 10 | * C2S for Red Hat Enterprise Linux 7: [HTML](/cac/guides/ssg-rhel7-guide-C2S.html) 11 | * Criminal Justice Information Services (CJIS) Security Policy: [HTML](/cac/guides/ssg-rhel7-guide-cjis.html) 12 | * Unclassified Information in Non-federal Information Systems and Organizations (NIST 800-171): [HTML](/cac/guides/ssg-rhel7-guide-cui.html) 13 | * Australian Cyber Security Centre (ACSC) Essential Eight: [HTML](/cac/guides/ssg-rhel7-guide-e8.html) 14 | * Health Insurance Portability and Accountability Act (HIPAA): [HTML](/cac/guides/ssg-rhel7-guide-hipaa.html) 15 | * NIST National Checklist Program Security Guide: [HTML](/cac/guides/ssg-rhel7-guide-ncp.html) 16 | * OSPP - Protection Profile for General Purpose Operating Systems v4.2.1: [HTML](/cac/guides/ssg-rhel7-guide-ospp.html) 17 | * PCI-DSS v3.2.1 Control Baseline for Red Hat Enterprise Linux 7: [HTML](/cac/guides/ssg-rhel7-guide-pci-dss.html) 18 | * Red Hat Corporate Profile for Certified Cloud Providers (RH CCP): [HTML](/cac/guides/ssg-rhel7-guide-rht-ccp.html) 19 | * Standard System Security Profile for Red Hat Enterprise Linux 7: [HTML](/cac/guides/ssg-rhel7-guide-standard.html) 20 | * DISA STIG for Red Hat Enterprise Linux 7: [HTML](/cac/guides/ssg-rhel7-guide-stig.html) 21 | * DRAFT - ANSSI DAT-NT28 (enhanced): [HTML](/cac/guides/ssg-rhel7-guide-anssi_nt28_enhanced.html) 22 | * DRAFT - ANSSI DAT-NT28 (high): [HTML](/cac/guides/ssg-rhel7-guide-anssi_nt28_high.html) 23 | * DRAFT - ANSSI DAT-NT28 (intermediary): [HTML](/cac/guides/ssg-rhel7-guide-anssi_nt28_intermediary.html) 24 | * DRAFT - ANSSI DAT-NT28 (minimal): [HTML](/cac/guides/ssg-rhel7-guide-anssi_nt28_minimal.html) 25 | 26 | DISA STIG SRG Mapping Table: [HTML](/cac/tables/table-rhel7-srgmap-flat.html), [CSV](/cac/tables/table-rhel7-srgmap-flat.csv) 27 | 28 | SCAP content 29 | * All in one DataStream: [SCAP 1.3](/cac/ssg-rhel7-ds.xml), [SCAP 1.2](/cac/ssg-rhel7-ds-1.2.xml) 30 | * Checklist: [XCCDF 1.2](/cac/ssg-rhel7-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-rhel7-xccdf.xml) 31 | * Assessment Details: [OVAL](/cac/ssg-rhel7-oval.xml) 32 | * Questionnaires: [OCIL](/cac/ssg-rhel7-ocil.xml) 33 | 34 | 35 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/rhel-8/Overview.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | Continue to overview of [SCAP Resources](/ato/products/rhel-8/SCAP) available in general or [STIG Resources](/ato/products/rhel-8/STIG) in particular. 4 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/rhel-8/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for Red Hat Enterprise Linux 8 is being developed under [ComplianceAsCode project](https://github.com/ComplianceAsCode/content). This content is periodically shipped within Red Hat Enterprise Linux 8, scap-security-guide package. Configuration compliance with the given SCAP content can be assessed automatically using [OpenSCAP tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/scanning-the-system-for-security-compliance-and-vulnerabilities_security-hardening). 4 | 5 | ### Latest greatest documents 6 | Available Profiles: 7 | * Criminal Justice Information Services (CJIS) Security Policy: [HTML](/cac/guides/ssg-rhel8-guide-cjis.html) 8 | * Unclassified Information in Non-federal Information Systems and Organizations (NIST 800-171): [HTML](/cac/guides/ssg-rhel8-guide-cui.html) 9 | * Australian Cyber Security Centre (ACSC) Essential Eight: [HTML](/cac/guides/ssg-rhel8-guide-e8.html) 10 | * Health Insurance Portability and Accountability Act (HIPAA): [HTML](/cac/guides/ssg-rhel8-guide-hipaa.html) 11 | * Protection Profile for General Purpose Operating Systems: [HTML](/cac/guides/ssg-rhel8-guide-ospp.html) 12 | * PCI-DSS v3.2.1 Control Baseline for Red Hat Enterprise Linux 8: [HTML](/cac/guides/ssg-rhel8-guide-pci-dss.html) 13 | * Red Hat Corporate Profile for Certified Cloud Providers (RH CCP): [HTML](/cac/guides/ssg-rhel8-guide-rht-ccp.html) 14 | * Standard System Security Profile for Red Hat Enterprise Linux 8: [HTML](/cac/guides/ssg-rhel8-guide-standard.html) 15 | * [DRAFT] DISA STIG for Red Hat Enterprise Linux 8: [HTML](/cac/guides/ssg-rhel8-guide-stig.html) [Details](/ato/products/rhel-8/STIG) 16 | 17 | SCAP content 18 | * All in one DataStream: [SCAP 1.3](/cac/ssg-rhel8-ds.xml), [SCAP 1.2](/cac/ssg-rhel8-ds-1.2.xml) 19 | * Checklist: [XCCDF 1.2](/cac/ssg-rhel8-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-rhel8-xccdf.xml) 20 | * Assessment Details: [OVAL](/cac/ssg-rhel8-oval.xml) 21 | * Questionnaires: [OCIL](/cac/ssg-rhel8-ocil.xml) 22 | 23 | 24 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/rhel-8/STIG.md: -------------------------------------------------------------------------------- 1 | ## STIG 2 | 3 | STIG guidance in form of SCAP content is being developed under [ComplianceAsCode project](https://github.com/ComplianceAsCode/content). Configuration compliance with the given SCAP content can be assessed automatically using [OpenSCAP tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/scanning-the-system-for-security-compliance-and-vulnerabilities_security-hardening). 4 | 5 | ### Latest development documents 6 | This is a *draft* profile for STIG. This profile is being developed under the DoD consensus model to become a STIG in coordination with DISA FSO. Latest version of the documents can be obtained from upstream project or under following links. 7 | 8 | Available downloads: 9 | * Implementation Guide: [HTML](/cac/guides/ssg-rhel8-guide-stig.html) 10 | * SRG Mapping Table: [HTML](/cac/tables/table-rhel8-srgmap-flat.html), [CSV](/cac/tables/table-rhel8-srgmap-flat.csv) 11 | * SCAP content 12 | * All in one DataStream: [SCAP 1.3](/cac/ssg-rhel8-ds.xml), [SCAP 1.2](/cac/ssg-rhel8-ds-1.2.xml) 13 | * Checklist: [XCCDF 1.2](/cac/ssg-rhel8-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-rhel8-xccdf.xml) 14 | * Assessment Details: [OVAL](/cac/ssg-rhel8-oval.xml) 15 | * Questionnaires: [OCIL](/cac/ssg-rhel8-ocil.xml) 16 | * All in one remediation script: [Ansible Playbook](/cac/ansible/rhel8-playbook-stig.yml), [Bash](/cac/bash/rhel8-script-stig.sh) 17 | 18 | ### Download released content available at NIST NVD 19 | * [NIST National Checklist for Red Hat Enterprise Linux 8.x content v0.1.48 Checklist Details](https://nvd.nist.gov/ncp/checklist/909) 20 | * [Red Hat KCS Article](https://access.redhat.com/articles/5067391) 21 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/virtualization-host/Overview.md: -------------------------------------------------------------------------------- 1 | ## Common Criteria 2 | Red Hat Virtualization Host has not undergone Common Criteria certification. A future certification 3 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) is being considered. 4 | 5 | To help Red Hat track demand for a Common Criteria certification of Red Hat Virtualization Host, please open a 6 | customer support case requesting an evaluation. 7 | 8 | ## FIPS 140-2 9 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 10 | 11 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic 12 | subsystems or components, such as OpenSSL and OpenSSH, are validated. 13 | 14 | When Red Hat Virtualization Host runs on Red Hat Enterprise Linux 7.x, the following FIPS 140-2 validations 15 | are retained: 16 | 17 | | Product | Component | Version | NIST Certificate | Status | Sunset/Expiration? | 18 | |:--------|:----------|:-------:|:----------------:|:------:|:------------------:| 19 | | Red Hat Enterprise Linux 7.x | OpenSSL | 5.0 | [#3016](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3016) | ACTIVE | 9/14/2022 | 20 | | Red Hat Enterprise Linux 7.x | OpenSSH Client | 5.0 | [#3067](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3067) | ACTIVE | 11/26/2022 | 21 | | Red Hat Enterprise Linux 7.x | OpenSSH Server | 5.0 | [#3063](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3063) | ACTIVE | 11/13/2022 | 22 | | Red Hat Enterprise Linux 7.x | Libreswan | 5.0 | [#3083](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3083) | ACTIVE | 12/18/2022 | 23 | | Red Hat Enterprise Linux 7.x | GnuTLS | 5.0 | [#3012](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3012) | ACTIVE | 9/7/2022 | 24 | | Red Hat Enterprise Linux 7.x | libgcrypt | 5.0 | [#2657](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/2657) | ACTIVE | 6/12/2021 | 25 | | Red Hat Enterprise Linux 7.x | NSS | 5.0 | [#3070](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3070) | ACTIVE | 2/7/2023 | 26 | 27 | #### Known Issues with FIPS 140-2 Enablement 28 | Coming Soon. 29 | 30 | ### USGv6 / IPv6 31 | Coming Soon. 32 | 33 | ### Section 508 / VPAT 34 | Coming Soon. 35 | 36 | ### Configuration Guides 37 | Coming Soon. 38 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/virtualization-host/SCAP.md: -------------------------------------------------------------------------------- 1 | ## SCAP 2 | 3 | SCAP content for Red Hat Virtualization Host is being developed under [ComplianceAsCode project](https://github.com/ComplianceAsCode/content). Configuration compliance with the given SCAP content can be assessed automatically using [OpenSCAP tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/configuration-compliance-scanning_scanning-the-system-for-configuration-compliance-and-vulnerabilities). 4 | 5 | ### Released content available at NIST NVD 6 | * [NIST National Checklist for Red Hat Virtualization Host 4.x content](https://nvd.nist.gov/ncp/checklist/908) 7 | 8 | ### Latest greatest documents for RHEL8 9 | Available profiles: 10 | * [DRAFT] DISA STIG for Red Hat Enterprise Linux Virtualization Host (RHELH) [HTML](/cac/guides/ssg-rhel8-guide-rhelh-stig.html) 11 | * VPP - Protection Profile for Virtualization v. 1.0 for Red Hat Enterprise Linux Hypervisor (RHELH) [HTML](/cac/guides/ssg-rhel8-guide-rhelh-vpp.html) 12 | 13 | SCAP content 14 | * All in one DataStream: [SCAP 1.3](/cac/ssg-rhel8-ds.xml), [SCAP 1.2](/cac/ssg-rhel8-ds-1.2.xml) 15 | * Checklist: [XCCDF 1.2](/cac/ssg-rhel8-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-rhel8-xccdf.xml) 16 | * Assessment Details: [OVAL](/cac/ssg-rhel8-oval.xml) 17 | * Questionnaires: [OCIL](/cac/ssg-rhel8-ocil.xml) 18 | 19 | ### Latest greatest documents for RHEL7 20 | Available Profiles: 21 | * [DRAFT] DISA STIG for Red Hat Enterprise Linux Virtualization Host (RHELH) [HTML](/cac/guides/ssg-rhel7-guide-rhelh-stig.html) 22 | * VPP - Protection Profile for Virtualization v. 1.0 for Red Hat Enterprise Linux Hypervisor (RHELH) [HTML](/cac/guides/ssg-rhel7-guide-rhelh-vpp.html) 23 | 24 | SCAP content 25 | * All in one DataStream: [SCAP 1.3](/cac/ssg-rhel7-ds.xml), [SCAP 1.2](/cac/ssg-rhel7-ds-1.2.xml) 26 | * Checklist: [XCCDF 1.2](/cac/ssg-rhel7-xccdf-1.2.xml), [XCCDF 1.1](/cac/ssg-rhel7-xccdf.xml) 27 | * Assessment Details: [OVAL](/cac/ssg-rhel7-oval.xml) 28 | * Questionnaires: [OCIL](/cac/ssg-rhel7-ocil.xml) 29 | 30 | 31 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/products/virtualization-manager/Overview.md: -------------------------------------------------------------------------------- 1 | ## Common Criteria 2 | Red Hat Virtualization Manager has not undergone Common Criteria certification. A future certification 3 | against the [NIAP Protection Profile for Application Software](https://www.niap-ccevs.org/Profile/Info.cfm?PPID=394&id=394) is being considered. 4 | 5 | To help Red Hat track demand for a Common Criteria certification of Red Hat Virtualization Manager, please open a 6 | customer support case requesting an evaluation. 7 | 8 | ## FIPS 140-2 9 | Federal Information Processing Standard 140-2 is a legal requirement ensuring cryptographic tools implement algorithms properly. Vendors must certify their cryptographic implementations through NIST's [Cryptographic Module Validation Program](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program). 10 | 11 | FIPS 140-2 validation does not constitute an entire product. Rather, underlying cryptographic 12 | subsystems or components, such as OpenSSL and OpenSSH, are validated. 13 | 14 | When Red Hat Virtualization Manager runs on Red Hat Enterprise Linux 7.x, the following FIPS 140-2 validations 15 | are retained: 16 | 17 | | Product | Component | Version | NIST Certificate | Status | Sunset/Expiration? | 18 | |:--------|:----------|:-------:|:----------------:|:------:|:------------------:| 19 | | Red Hat Enterprise Linux 7.x | OpenSSL | 5.0 | [#3016](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3016) | ACTIVE | 9/14/2022 | 20 | | Red Hat Enterprise Linux 7.x | OpenSSH Client | 5.0 | [#3067](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3067) | ACTIVE | 11/26/2022 | 21 | | Red Hat Enterprise Linux 7.x | OpenSSH Server | 5.0 | [#3063](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3063) | ACTIVE | 11/13/2022 | 22 | | Red Hat Enterprise Linux 7.x | Libreswan | 5.0 | [#3083](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3083) | ACTIVE | 12/18/2022 | 23 | | Red Hat Enterprise Linux 7.x | GnuTLS | 5.0 | [#3012](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3012) | ACTIVE | 9/7/2022 | 24 | | Red Hat Enterprise Linux 7.x | libgcrypt | 5.0 | [#2657](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/2657) | ACTIVE | 6/12/2021 | 25 | | Red Hat Enterprise Linux 7.x | NSS | 5.0 | [#3070](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3070) | ACTIVE | 2/7/2023 | 26 | 27 | #### Known Issues with FIPS 140-2 Enablement 28 | Coming Soon. 29 | 30 | ### USGv6 / IPv6 31 | Coming Soon. 32 | 33 | ### Section 508 / VPAT 34 | Coming Soon. 35 | 36 | ### Configuration Guides 37 | Coming Soon. 38 | -------------------------------------------------------------------------------- /assets/src/app/assets/markdown/vulnerability-management-plan.md: -------------------------------------------------------------------------------- 1 | # Vulnerability Management Plan 2 | 3 | ATO Documents opener. 4 | 5 | 6 | ## Changelog 7 | 8 | This record shall be maintained throughout the life of the document. Each published update shall be recorded. 9 | 10 | | Date | Description of Change | Made by | 11 | |------------|-----------------------------|-----------------------------------| 12 | | 7-MAR-2018 | Initial draft | Shawn Wells \| | 13 | 14 | 15 | ## Process Overview 16 | 17 | The vulnerability management process begins with vulnerabilities being identified 18 | or reported to Red Hat's Product Security team. 19 | 20 | Red Hat Product Security rates the impact of security issues found in Red Hat 21 | products using a four-point scale (Low, Moderate, Important, Critical), as well 22 | as Common Vulnerability Scoring System (CVSS) base scores. These provide a 23 | prioritized risk assessment to help you understand and schedule upgrades to your 24 | systems, enabling informed decisions on the risk each issue places on your 25 | unique environment. 26 | 27 | The four-point scale tells you how serious Red Hat considers an issue to be, 28 | helping system operators judge the severity and determine what the most 29 | important updates are. The scale takes into account the potential risk based 30 | on a technical analysis of the exact flaw and its type, but not the current 31 | threat level; a given rating will not change if an exploit or worm is later 32 | released for a flaw, or if one is available before the release of a fix. 33 | 34 | | Severity Rating | Description | 35 | |:---------------:|:-----------| 36 | | Critical Impact | This rating is given to flaws that could be easily exploited by a remote unauthenticated attacker and lead to system compromise (arbitrary code execution) without requiring user interation. These are the types of vulnerabilities that can be exploited by worms. Flaws that require an authenticated remote user, a local user, or an unlikely configuration are not classed as Critical impact.| 37 | | Important Impact| This rating is given to flaws that can easily compromise the confidentiality, integrity, or availability of resources. These are the typos of vulnerabilities that allow local users to gain privileges, allow unauthenticated remote users to view resources that should otherwise be protected by authentication, allow authenticated remote users to execute arbitrary code, or allow remote users to cause a denial of service.| 38 | | Moderate Impact | This rating is given to flaws that may be more difficult to exploit but could still lead to some compromose of the confidentiality, integrity, or availability of resources, under certain circumstances. These are the typoes of vulneravilities that could have had a Critical or Important impact but are less easily exploited based on a technical evaluation of the flaw, or affect unlikely configurations.| 39 | | Low Impact | This rating is given to all other issues that have a security impact. These are the types of vulnerabilities that are believed to require unlikely circumstances to be able to be exploited, or where successful exploit would give minimal consequences.| 40 | 41 | Additional information on Red Hat's Severity Ratings can be found at 42 | [Understanding Red Hat security ratings](https://access.redhat.com/security/updates/classification/). 43 | 44 | ### Differences Between NVD and Red Hat Scores 45 | For open source software shipped by multiple vendors, the CVSS base scores 46 | may vary for each vendor's version, depending on the version they ship, how they 47 | ship it, the platform, and even how the software is compiled. This makes scoring 48 | of vulnerabilities difficult for third-party vulnerability databases, such as 49 | the NIST National Vulnerability Database (NIST NVD), who can only give a single 50 | CVSS base score to each vulnerability. 51 | 52 | These differences can cause the scores to vary widely. For example, NVD rates 53 | Firefox flaws as having High impact metrics because the Firefox application 54 | is also available for Microsoft Windows, where it is common that the user is 55 | running Firefix with administrator privileges. For Red Hat Enterprise Linux, Low 56 | impact metrics are used, as Firefox is most likely to run as an unprivileged 57 | user. 58 | 59 | For these reasons, it is recommended that, whenever possible, CVSS base scores 60 | provided by Red Hat are given preference over third party scoring. 61 | 62 | ### Differences Between DISA IAVA and Red Hat Scores 63 | tbd tbd tbd 64 | 65 | 66 | 67 | ## Patch Implementation 68 | Should timely patching not be feasible, extensions are granted by the 69 | organization's Designated Approving Authority (DAA). The following 70 | considerations must be documented for each extension request: 71 | 72 | - The assessment of risk (e.g.; how vulnerable the system is to exploit) 73 | - How the system(s) will be monitored for exploitation (e.g.; use of mitigating tools) 74 | - A Fix Action Plan with a completion date 75 | 76 | The system owner, upon receipt of an official notification of a vulnerability 77 | notice, will take the following actions: 78 | 79 | 1. Access the DoD-CERT web page and retrieve the entire vulnerability notice message. 80 | 2. Notify SA, ISSO, and all appropriate staff of the vulnerability notice and inform the staff to access the DoD-CERT web page and retrieve the vulnerability notice message. 81 | 3. Acknowledge receipt of the vulnerability notification to the SMDC IAM. Acknowledgement must be completed within 5 days unless otherwise specified in the vulnerability notification. 82 | 4. Assess the impact of the vulnerability, apply the fix or obtain an extension if corrective actions cannot be implemented within the specified timeframe. Report the status for each vulnerability notice as it applies to every applicable asset within the information system. 83 | 5. Conduct random compliance checks on information system assets to validate the information being reported through the command channels. 84 | 85 | Information system owners can opt to make a vulnerability notice requirement more stringent than those required by DoD CERT. 86 | 87 | 88 | 89 | ## Patch Extension Request 90 | Should timely patching not be feasible, extensions are granted by the 91 | organization's Designated Approving Authority (DAA). The following 92 | considerations must be documented for each extension request: 93 | 94 | - The assessment of risk (e.g.; how vulnerable the system is to exploit) 95 | - How the system(s) will be monitored for exploitation (e.g.; use of mitigating tools) 96 | - A Fix Action Plan with a completion date 97 | 98 | 99 | 100 | ## Compliance Status 101 | Every asset potentially affected by a vulnerability notice will be labeled 102 | with one of the following "Compliance Status" identifies: 103 | 104 | **Open**: "Open" means the asset is impacted by a specific alert; however, no 105 | protective actions have been put in place. As a result, the vulnerability still 106 | exists. Most alerts are issued with a period of 30 days for compliance. An "open" 107 | status is acceptable during this 30-60 day period. However, if an asset becomes 108 | operational 30 days after the initial release of the alert, an "open" status is 109 | not acceptable. 110 | 111 | **Not Applicable**: "Not applicable" means the System Administrator (SA), 112 | Information System Security Officer (ISSO), Information System Security Manager 113 | (ISSM) or Program Manager (PM) has determined a recently released alert does not 114 | apply to the operational configuration of an asset. The responsible user who 115 | made this decision is required to maintain all documentation to justify the 116 | "Not Applicable" status. The management hierarchy or the DAA may request the 117 | documentation. Also, the documentation may be reviewed during the compliance 118 | validation process. 119 | 120 | **Fixed/In Compliance**: This status means the SA or ISSO has determined an 121 | asset is applicable to a recently released alert and is in compliance with the 122 | official patch or fix. 123 | 124 | **Extension Requested**: "Extension Requested" indicates that an extension 125 | request has been submitted for the asset and is in the process of being 126 | reviewed. There are two types of extension requests. First, the extension can be 127 | used in the traditional sense where the DAA accepts the mitigated risk associated 128 | with nonstandard official corrective action. Second, the extension can be employed 129 | by the user to request additional time to allow for corrective action to occur. 130 | This would be used for situations where corrective action cannot be implemented 131 | within the specified timeframe due to other factors (e.g.; equipment delivery, 132 | financial limitations, resource shortage, PMO actions, and other prerequisite 133 | tasks). 134 | 135 | **Extension Approved**: This status indicates that an extension request has been 136 | approved for a specified timeframe. Management is responsible for continuing to 137 | address the problem and ensure that mitigating controls are in place. An 138 | extension may be granted for extended periods with management involvement. See list below. 139 | 140 | | Period | Number of Days | Management | Fix Action Plan Requirement | 141 | |--------|----------------|------------|-----------------------------| 142 | | Original Compliance Period | 30 < original time period | IAM | * EMail tickler sent 15 days prior to compliance date polling activity fix status

* If asset will be in compliance - No action required.

* If asset will not be in compliance - IAM must submit a consolidated activity Plan of Action and Milestones (POA*M) to CIO 7 days prior to compliance date| 143 | | 1st Extension | Not to exceed 30 days | IAM, DAA | * EMail tickler sent 15 days prior to compliance date polling activity fix status.

* If asset will be in compliance - No action required.

* If asset will not be in compliance - IAM must submit a consolidated activity Plan of Action and Milestones (POA&M) to CIO 7 days prior to extension expiration.| 144 | | 2nd Extension | Not to exceed 60 days | IAM, DAA | * EMail tickler sent at 15-day intervals for compliance status check.| 145 | | Additional Extensions (if required) | Based on circumstances | DAA | TBD | 146 | 147 | **Extension Denied**: This status indicates that the Designated Approval 148 | Authority evaluated and denied an extension request. The SA/ISSO is responsible 149 | for immediately implementing corrective actions. 150 | 151 | **Extension Expired**: This status indicates that an approved extension has 152 | expired for the asset and that corrective actions must be implemented or that 153 | another extension request must be submitted. 154 | 155 | 156 | 157 | ## Contact Information 158 | For further information about the IAVA bulletin itself, DODCERT hotline can be reached at [703-607-4030](tel:703-607-4030), DSN [327-4030](tel:327-4030), or [1-800-357-4231](tel:1-800-357-4231); or via NIPRNet email at [iavacoordinator@jtfgno.mil](email:iavacoordinator@jtfgno.mil). 159 | 160 | Information pertaining directly to vulnerabilities is posted on the ASSIST web site at [http://www.jtfgno.mil/](http://www.jtfgno.mil). 161 | -------------------------------------------------------------------------------- /assets/src/app/ato/Charts/BarCharts.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { TextContent, Text } from '@patternfly/react-core'; 3 | import { Chart, ChartAxis, ChartBar, ChartStack, ChartVoronoiContainer } from '@patternfly/react-charts'; 4 | import { CompletionChartProps, CompletionChartsProps, controlsBaseUrl, customTheme, statusSort, sectionNames } from '@app/ato/Charts/common'; 5 | import { StatusColor } from '@app/ato/Products/DataList'; 6 | import { VictoryBarTTargetType } from 'victory-bar'; 7 | import { EventPropTypeInterface } from 'victory-core'; 8 | 9 | export const CompletionBarCharts = React.memo((props: CompletionChartsProps) => { 10 | const { data } = props; 11 | return ( 12 | 13 | { Object.keys(data).map((c) => { return ( 14 | 15 | 16 | {data[c].Certification} 17 | 18 | 19 | 20 | )}) } 21 | 22 | ) 23 | }) 24 | 25 | const CompletionBarChart = React.memo((props: CompletionChartProps) => { 26 | const pf = props.cs.PerFamily; 27 | const statuses = statusSort(Object.keys(pf).map((family) => Object.keys(pf[family])).reduce((a, b) => a.concat(b)).filter((value, index, self) => { 28 | return self.indexOf(value) === index; 29 | })) 30 | const data = statuses.map((status) => { 31 | return Object.keys(pf).map((family) => { 32 | var y = pf[family][status] 33 | y = y == undefined ? 0 : y 34 | return { x: family, y: y, status: status} 35 | }); 36 | }) 37 | const baseUrl = controlsBaseUrl(props.cs.Certification) 38 | const eventHandlers: EventPropTypeInterface[] = [{ 39 | target: "data", 40 | eventHandlers: { 41 | onClick: () => { 42 | return [{ 43 | target: "data", 44 | mutation: (props) => { 45 | window.open(baseUrl + props.datum.status + "§ion=" + props.datum.x); 46 | return null 47 | } 48 | }]; 49 | } 50 | } 51 | }] 52 | 53 | return ( 54 |
55 | `${datum.y} ${datum.status} responses for ${datum.x} (${sectionNames[datum.x]})`} constrainToVisibleArea />} 59 | legendData={statuses.map((status) => { return { name: status }})} 60 | legendOrientation="vertical" 61 | legendPosition="right" 62 | height={275} 63 | theme={customTheme(statuses, 'stack')} 64 | padding={{ 65 | bottom: 50, // Adjusted to accommodate legend 66 | left: 50, 67 | right: 140, 68 | top: 10 69 | }} 70 | width={700} 71 | > 72 | 73 | 74 | StatusColor[status])}> 75 | { data.map((statusData) => { return () } ) } 79 | 80 | 81 |
82 | ) 83 | }) 84 | 85 | 86 | -------------------------------------------------------------------------------- /assets/src/app/ato/Charts/CompletionCharts.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { PageSection } from '@patternfly/react-core'; 3 | import { Tabs, Tab } from '@patternfly/react-core'; 4 | import { ComponentStats } from '@app/ato/Charts/common' 5 | import { CompletionPieCharts} from '@app/ato/Charts/PieCharts' 6 | import { CompletionStackCharts } from '@app/ato/Charts/StackCharts' 7 | import { CompletionRadarCharts } from '@app/ato/Charts/RadarCharts' 8 | import { CompletionBarCharts } from '@app/ato/Charts/BarCharts' 9 | import * as Api from '@app/lib/api' 10 | import * as qs from '@app/lib/querystring' 11 | 12 | interface CompletionChartsProps { 13 | productId: string; 14 | } 15 | 16 | interface CompletionChartsState { 17 | activeTabKey: number; 18 | productId: string; 19 | data: ComponentStats; 20 | } 21 | 22 | const titleToId = { 23 | undefined: 0, 24 | "0": 0, 25 | "1": 1, 26 | "2": 2, 27 | "3": 3, 28 | } 29 | 30 | export class CompletionCharts extends React.PureComponent { 31 | constructor(props) { 32 | super(props); 33 | const params = qs.Parse() 34 | this.state = { 35 | activeTabKey: titleToId[params.tab], 36 | data: {}, 37 | productId: props.productId, 38 | 39 | }; 40 | this.handleTabClick = this.handleTabClick.bind(this); 41 | this.reloadData() 42 | } 43 | 44 | handleTabClick(event, tabIndex){ 45 | qs.Set({'tab': tabIndex}) 46 | this.setState({ 47 | activeTabKey: tabIndex 48 | }); 49 | }; 50 | 51 | static getDerivedStateFromProps(props, state) { 52 | if (state.productId != props.productId) { 53 | return {productId: props.productId, data: {}} 54 | } 55 | return null; 56 | } 57 | 58 | componentDidUpdate() { 59 | if (Object.keys(this.state.data).length == 0 && this.state.productId != 'select') { 60 | this.reloadData() 61 | } 62 | } 63 | 64 | reloadData() { 65 | Api.statistics(this.state.productId).then(data => {this.setState({data: data})}) 66 | } 67 | 68 | render() { 69 | return ( 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | ); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /assets/src/app/ato/Charts/PieCharts.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { TextContent, Text } from '@patternfly/react-core'; 3 | import { ChartPie } from '@patternfly/react-charts'; 4 | import { CompletionChartProps, CompletionChartsProps, controlsBaseUrl, customTheme } from '@app/ato/Charts/common' 5 | 6 | export const CompletionPieCharts = React.memo((props: CompletionChartsProps) => { 7 | const { data } = props; 8 | return ( 9 | 10 | { Object.keys(data).map((c) => { return ( 11 | 12 | 13 | {data[c].Certification} 14 | 15 | 16 | 17 | )}) } 18 | 19 | ) 20 | }) 21 | 22 | const CertificationCompletionPieChart = React.memo((props: CompletionChartProps) => { 23 | const res = props.cs.History[props.cs.History.length - 1].Stats 24 | const data = Object.keys(res).map((c) => { 25 | return {"x": c, "y": res[c]} 26 | }) 27 | const legend = Object.keys(res).map((c) => { 28 | return {"name": c + ": " + res[c]} 29 | }) 30 | const baseUrl = controlsBaseUrl(props.cs.Certification) 31 | return ( 32 |
33 | `${datum.x}: ${datum.y}`} 40 | legendData={legend} 41 | legendOrientation="vertical" 42 | legendPosition="right" 43 | events={[{ 44 | target: "data", 45 | eventHandlers: { 46 | onClick: () => { 47 | return [{ 48 | target: "data", 49 | mutation: (props) => { 50 | window.open(baseUrl + data[props.index].x); 51 | return null 52 | } 53 | }]; 54 | } 55 | } 56 | }]} 57 | padding={{ 58 | bottom: 20, 59 | left: 20, 60 | right: 180, // Adjusted to accommodate legend 61 | top: 20 62 | }} 63 | theme={customTheme(data.map((s) => s.x) , 'pie')} 64 | width={350} 65 | /> 66 |
67 | ) 68 | }) 69 | -------------------------------------------------------------------------------- /assets/src/app/ato/Charts/RadarCharts.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { TextContent, Text } from '@patternfly/react-core'; 3 | import { CompletionChartProps, CompletionChartsProps, controlsBaseUrl, statusSort, sectionNames } from '@app/ato/Charts/common'; 4 | import { VictoryChart, VictoryBar, VictoryPolarAxis, VictoryStack, VictoryTheme, VictoryTooltip } from 'victory'; 5 | import { StatusColor } from '@app/ato/Products/DataList'; 6 | import { VictoryBarTTargetType } from 'victory-bar'; 7 | import { EventPropTypeInterface } from 'victory-core'; 8 | 9 | export const CompletionRadarCharts = React.memo((props: CompletionChartsProps) => { 10 | const { data } = props; 11 | return ( 12 | 13 | { Object.keys(data).map((c) => { return ( 14 | 15 | 16 | {data[c].Certification} 17 | 18 | 19 | 20 | )}) } 21 | 22 | ) 23 | }) 24 | 25 | const CompletionRadarChart = React.memo((props: CompletionChartProps) => { 26 | const pf = props.cs.PerFamily; 27 | const statuses = statusSort(Object.keys(pf).map((family) => Object.keys(pf[family])).reduce((a, b) => a.concat(b)).filter((value, index, self) => { 28 | return self.indexOf(value) === index; 29 | })) 30 | const controlsPerFamily = Object.keys(pf).reduce((map, family) => { 31 | map[family] =Object.keys(pf[family]).map((status) => pf[family][status]).reduce((a, b) => a + b); 32 | return map; 33 | }, {}) 34 | const data = statuses.map((status) => { 35 | return Object.keys(pf).map((family) => { 36 | var y = pf[family][status] 37 | y = y == undefined ? 0 : y 38 | return { x: family, y: y / controlsPerFamily[family], status: status, count: y } 39 | }); 40 | }) 41 | const baseUrl = controlsBaseUrl(props.cs.Certification) 42 | const eventHandlers: EventPropTypeInterface[] = [{ 43 | target: "data", 44 | eventHandlers: { 45 | onClick: () => { 46 | return [{ 47 | target: "data", 48 | mutation: (props) => { 49 | window.open(baseUrl + props.datum.status + "§ion=" + props.datum.x); 50 | return null 51 | } 52 | }]; 53 | } 54 | } 55 | }] 56 | 57 | return ( 58 |
59 | 62 | { 63 | Object.keys(pf).map((d, i) => { 64 | return ( 65 | 72 | ); 73 | }) 74 | } 75 | 76 | StatusColor[status]) } 78 | style={{ data: { width: 20} }} 79 | > 80 | { data.map((statusData) => { return ( `${datum.count} ${datum.status} responses for ${datum.x} (${sectionNames[datum.x]})`} 82 | 83 | labelComponent={} 84 | events={eventHandlers} 85 | key={statusData[0].x} data={statusData} />) } ) } 86 | 87 | 88 |
89 | ); 90 | }) 91 | -------------------------------------------------------------------------------- /assets/src/app/ato/Charts/StackCharts.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { TextContent, Text } from '@patternfly/react-core'; 3 | import { ChartVoronoiContainer, ChartAreaProps } from '@patternfly/react-charts'; 4 | import { CompletionChartProps, CompletionChartsProps, controlsBaseUrl, customTheme } from '@app/ato/Charts/common' 5 | import { Chart, ChartArea, ChartAxis, ChartStack } from '@patternfly/react-charts'; 6 | import { VictoryAreaTTargetType } from 'victory-area'; 7 | import { EventPropTypeInterface } from 'victory-core'; 8 | 9 | export const CompletionStackCharts = React.memo((props: CompletionChartsProps) => { 10 | const { data } = props; 11 | return ( 12 | 13 | { Object.keys(data).map((c) => { return ( 14 | 15 | 16 | {data[c].Certification} 17 | 18 | 19 | 20 | )}) } 21 | 22 | ) 23 | }) 24 | 25 | const CompletionStackChart = React.memo((props: CompletionChartProps) => { 26 | const statuses = props.cs.History.map((s) => Object.keys(s.Stats)).reduce((a, b) => a.concat(b)).filter((value, index, self) => { 27 | return self.indexOf(value) === index; 28 | }) 29 | 30 | const result = statuses.map((status) => { 31 | return props.cs.History.map((snapshot, k) => { 32 | const y = snapshot.Stats[status] 33 | return { 'name': status, 'x': new Date(snapshot.Time), 'y': y == undefined ? 0 : y } 34 | }) 35 | }) 36 | 37 | const legendData = statuses.map((status) => { 38 | return { name: status } 39 | }) 40 | const maxDomain = Object.values(props.cs.History[0].Stats).reduce((a, b) => { return (a as number) + (b as number) }) as number 41 | const baseUrl = controlsBaseUrl(props.cs.Certification) 42 | const eventHandlers: EventPropTypeInterface[] = [{ 43 | target: "data", 44 | eventHandlers: { 45 | onClick: () => { 46 | return [{ 47 | target: "data", 48 | mutation: (props) => { 49 | window.open(baseUrl + props.data[0].name); 50 | return null 51 | } 52 | }]; 53 | } 54 | } 55 | }] 56 | 57 | return ( 58 |
59 | `${datum.name}: ${datum.y}`} constrainToVisibleArea />} 76 | > 77 | 78 | 79 | 80 | { result.map((statusArea) => { 81 | return () 82 | }) } 83 | 84 | 85 |
86 | ); 87 | }) 88 | -------------------------------------------------------------------------------- /assets/src/app/ato/Charts/common.tsx: -------------------------------------------------------------------------------- 1 | import { ChartThemeColor, getTheme, ChartThemeVariant } from '@patternfly/react-charts'; 2 | import { StatusColor } from '@app/ato/Products/DataList' 3 | 4 | export interface CompletionChartsProps { 5 | data: ComponentStats; 6 | } 7 | 8 | export interface CompletionChartProps { 9 | cs: CertificationStats; 10 | } 11 | 12 | export function controlsBaseUrl(standardName: string) { 13 | return window.location.pathname.replace('/Charts', '/NIST-800-53') + "?standard=" + standardName + "&status=" 14 | } 15 | 16 | export function customTheme(statuses: any[], chartType: string) { 17 | const theme = getTheme(ChartThemeColor.blue, ChartThemeVariant.light) 18 | statuses.forEach((status, i) => { 19 | theme[chartType].colorScale[i] = StatusColor[status] 20 | if (theme.legend) { 21 | theme.legend!.colorScale![i] = StatusColor[status] 22 | } 23 | }) 24 | return theme 25 | } 26 | 27 | export type ComponentStats = {[certID: string]: CertificationStats} 28 | 29 | export interface CertificationStats { 30 | Certification: string; 31 | History: ResultSnapshot[]; 32 | PerFamily: {[FamilyId: string]: ControlResponses}; 33 | } 34 | 35 | interface ResultSnapshot { 36 | Time: string; 37 | Stats: ControlResponses; 38 | } 39 | 40 | type ControlResponses = {[CtrlId: string]: number}; 41 | 42 | const statusOrder = { 43 | 'complete': 1, 44 | 'not applicable': 2, 45 | 'partial': 3, 46 | 'planned': 4, 47 | 'unsatisfied': 5, 48 | 'unknown': 6, 49 | 'none': 7, 50 | } 51 | 52 | export function statusSort(statuses: string[]) { 53 | return statuses.sort((a, b) => { 54 | return statusOrder[a] - statusOrder[b] 55 | }) 56 | } 57 | 58 | export const sectionNames = { 59 | 'AC': 'Access Control', 60 | 'AT': 'Awareness and Training', 61 | 'AU': 'Audit and Accountability', 62 | 'CA': 'Security Assessment & Authorization', 63 | 'CM': 'Configuration Management', 64 | 'CP': 'Contingency Planning', 65 | 'IA': 'Identification and Authentication', 66 | 'IR': 'Incident Response', 67 | 'MA': 'Maintenance', 68 | 'MP': 'Media Protection', 69 | 'PE': 'Physical & Environmental Protection', 70 | 'PL': 'Planning', 71 | 'PS': 'Personnel Security', 72 | 'RA': 'Risk Management', 73 | 'SA': 'System and Services Acquisition', 74 | 'SC': 'Systems and Communications Protection', 75 | 'SI': 'System and Information Integrity', 76 | }; 77 | -------------------------------------------------------------------------------- /assets/src/app/ato/Documents/Documents.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Page, PageSection, PageSectionVariants } from '@patternfly/react-core'; 3 | import { Flex, FlexItem } from '@patternfly/react-core'; 4 | 5 | import VMP from '@app/assets/markdown/vulnerability-management-plan.md'; 6 | import TP from '@app/assets/markdown/training-plan.md'; 7 | import { Markdown } from '@app/lib/markdown'; 8 | import { ComponentSSPTemplates } from '@app/ato/Documents/SSPTemplates'; 9 | 10 | const Document: React.FunctionComponent = (props) => { 11 | return ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | {props.children} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ) 29 | } 30 | 31 | const ATOVulnerabilityManagementPlan: React.FunctionComponent = (props) => { 32 | return (); 33 | } 34 | 35 | const ATOTrainingPlan: React.FunctionComponent = (props) => { 36 | return (); 37 | } 38 | 39 | export { ATOVulnerabilityManagementPlan, ATOTrainingPlan, ComponentSSPTemplates }; 40 | -------------------------------------------------------------------------------- /assets/src/app/ato/Documents/Overview.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { PageSection, PageSectionVariants } from '@patternfly/react-core'; 3 | import { Page, 4 | Card, 5 | CardBody, 6 | CardHeader, 7 | Gallery, 8 | GalleryItem, 9 | TextContent, 10 | Text, 11 | } from '@patternfly/react-core'; 12 | import { NavLink } from 'react-router-dom'; 13 | import { BookReaderIcon, GhostIcon } from '@patternfly/react-icons'; 14 | 15 | const ATODocuments: React.FunctionComponent = (props) => { 16 | return ( 17 | 18 | 19 | 20 | ATO Documents 21 | A&A Templates 22 | 23 | Red Hat Public Sector is in the process of open sourcing ATO artifacts. 24 | Developed with US Government agencies and system integrators, these templates are 25 | tailored for the operation of Red Hat technologies and complement 26 | organizational-level policies and procedures. 27 | 28 | Many of these documents are undergoing prepublication review for open source release. 29 | As that happens they will be posted here! 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |   40 | 41 | Vulnerability Management 42 | 43 | 44 | 45 | The vulnerability management process begins with vulnerabilities being identified or reported to Red Hat’s Product Security team. 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |   54 | 55 | Security Awareness 56 | 57 | 58 | 59 | This resource has been compiled to assist with Security Awareness Training requirements. 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | ); 69 | } 70 | 71 | export { ATODocuments }; 72 | -------------------------------------------------------------------------------- /assets/src/app/ato/Documents/SSPTemplates.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Flex, FlexItem, 3 | Page, PageSection, PageSectionVariants, 4 | Text, TextContent 5 | } from '@patternfly/react-core'; 6 | import { FileAltIcon, FileCodeIcon, FileWordIcon } from '@patternfly/react-icons'; 7 | import { Table, TableBody, TableHeader, TableVariant } from '@patternfly/react-table'; 8 | import * as React from 'react'; 9 | 10 | interface FedRAMPsProps { 11 | productID: string; 12 | } 13 | 14 | class ComponentSSPTemplates extends React.Component { 15 | columns = ['FedRAMP Low', 'FedRAMP Moderate', 'FedRAMP High']; 16 | 17 | buildRows(product: string) { 18 | return [ 19 | [ 20 | this.FedRAMPLink(product, "Low", "docx"), 21 | this.FedRAMPLink(product, "Moderate", "docx"), 22 | this.FedRAMPLink(product, "High", "docx"), 23 | ], 24 | [ 25 | this.FedRAMPLink(product, "Low", "xml"), 26 | this.FedRAMPLink(product, "Moderate", "xml"), 27 | this.FedRAMPLink(product, "High", "xml"), 28 | ], 29 | [ 30 | this.FedRAMPLink(product, "Low", "json"), 31 | this.FedRAMPLink(product, "Moderate", "json"), 32 | this.FedRAMPLink(product, "High", "json"), 33 | ] 34 | ] 35 | } 36 | 37 | private FedRAMPLink(product: string, _level: string, _format: string) { 38 | var icon = 39 | 40 | switch (_format) { 41 | case "xml": 42 | icon = ; 43 | break; 44 | case "docx": 45 | icon = ; 46 | break; 47 | } 48 | var oscal = _format != "docx" 49 | 50 | return ( 51 | 52 | {icon} {oscal ? ".oscal" : ""}.{_format} 53 | 54 | ); 55 | } 56 | 57 | render() { 58 | // const textMod = {modifier: 'flex-2' as 'flex-default', breakpoint: 'md' as 'md'}; 59 | // const emptyMod = {modifier: 'flex-1' as 'flex-default', breakpoint: 'md' as 'md'}; 60 | return ( 61 | 62 | 63 | 64 | 65 | 66 | 67 | SSP Templates 68 | 69 | The FedRAMP templates are dynamically generated using the FedRAMP Templater tool, originally created by GSA's 18F and then rewritten to adopt OSCAL. An automated build system incorporates Red Hat's OpenControl Content directly into the FedRAMP Templates provided by the GSA FedRAMP PMO. 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 85 | 86 | 87 |
88 |
89 |
90 |
91 | ) 92 | } 93 | } 94 | 95 | export { ComponentSSPTemplates }; 96 | -------------------------------------------------------------------------------- /assets/src/app/ato/GettingStarted.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import pic from 'assets/src/app/assets/images/RMF-steps-all.png'; 3 | import { Brand, Flex, FlexItem, PageSection, PageSectionVariants, TextListVariants } from '@patternfly/react-core'; 4 | import { 5 | Page, TextContent, Text, TextList, TextListItem, TextVariants, 6 | } from '@patternfly/react-core'; 7 | 8 | const GettingStarted: React.FunctionComponent = () => { 9 | return ( 10 | 11 | 12 | 13 | {/* Getting Started */} 14 | Getting Started 15 | 16 | Red Hat’s ATO Pathways was created to provide resources that help accelerate your ATO (Authority/Authorization To Operate) process. This is made possible by combining open source projects that were spearheaded by Red Hat and still actively maintained in order to give our customers the necessary content needed for our products that help assist in the overall development of an ATO. 17 | 18 | 19 | {/* What Exactly is an ATO? */} 20 | What Exactly is an ATO? 21 | 22 | At a high level, as defined by the National Institute of Standards and Technology (NIST), an ATO is: 23 | 24 | ... an official management decision given by a senior organizational official to authorize operation of an information system and to explicitly accept the risk to organizational operations (including mission, functions, image, or reputation), organizational assets, individuals, other organizations, and the Nation based on the implementation of an agreed-upon set of security controls. 25 | 26 | 27 | 28 | It's your agency authority certifying your system is ready for day 2 operations: system availability, routine maintenance, monitoring, and lots of other concerns. 29 | 30 | 31 | The ATO process can be lengthy and daunting if not familiar with it. This process is formally defined by NIST’s Risk Management Framework (RMF) and consists of the following steps: 32 | 33 | 34 | {/* ATO PROCESS Picture + Ordered List */} 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Prepare 43 | Categorize Information System 44 | Select Security Controls 45 | Implement Security Controls 46 | Assess Security Controls 47 | Authorize Information System 48 | Monitor Security Controls 49 | 50 | 51 | 52 | 53 | 54 | {/* How does ATO Pathways Help? */} 55 | How does ATO Pathways Help? 56 | 57 | In order to better serve our customers who seek to attain an ATO with our products, we felt it was necessary to provide general guidance to the NIST 800-53 catalog of security and privacy controls. These internal evaluations help not only to provide the control responses for NIST 800-53, but also helps drive our engineering efforts in ensuring we are complying with these controls. 58 | 59 | 60 | On top of providing control responses for products, we also provide Security Content Automation Protocol (SCAP) content generated from our ComplianceAsCode project to assist with scanning and remediation of information systems. 61 | 62 | 63 | We’ve also introduced a new feature that allow you the ability to generate FedRAMP templates dynamically based on the product chosen. Again, the idea behind this is to help consumers get a head start on the ATO process. 64 | 65 | 66 | {/* Looking Ahead */} 67 | Looking Ahead 68 | 69 | More NIST 800-53 product assessments to be completed are on the horizon. We are planning on providing some role-based guides to assist consumers in finding the right content depending on their responsibilities. 70 | 71 | 72 | As always, your feedback and/or contributions is most important. There are many projects in which you can help (see the about button in the upper right corner for more information). 73 | 74 | 75 | {/* Role-based guides 76 | 77 | 78 | Auditors 79 | 80 | Content to assist with system accreditation based on the NIST Risk Management Framework. Materials include Security Requirement Traceability Matrixes, product certification materials (Common Criteria, FIPS), and other ATO package documents. 81 | 82 | 83 | 84 | Administrators 85 | 86 | Resources needed to implement Red Hat technologies in accordance with Government security regulations. Materials include Ansible playbooks, SCAP datastreams, kickstart files, and supporting documentation. 87 | 88 | 89 | 90 | Security Professionals 91 | 92 | You are a security specialist that helps define security requirements and has a deep understanding of how to analyze systems for security threats and vulnerabilities. 93 | 94 | 95 | 96 | Developers/Application Administrators 97 | 98 | You are a developer that builds software and systems that must be hardened to a security compliance baseline. Your goal is to understand early in the process what the security engineering you will need to implement to be compliant. 99 | 100 | 101 | */} 102 | 103 | 104 | 105 | ); 106 | } 107 | 108 | export { GettingStarted }; 109 | -------------------------------------------------------------------------------- /assets/src/app/ato/Products/Product.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { 3 | Alert, 4 | ApplicationLauncher, ApplicationLauncherItem, 5 | DropdownPosition, 6 | Page, PageSection, PageSectionVariants, 7 | TextContent, 8 | Text, 9 | PageHeader, 10 | } from '@patternfly/react-core'; 11 | import { Spinner } from '@patternfly/react-core'; 12 | import { EditAltIcon } from '@patternfly/react-icons' 13 | 14 | import * as Api from '@app/lib/api' 15 | import { Markdown } from '@app/lib/markdown'; 16 | import { ProductIdOverride, ProductInfo } from '@app/ato/Products/Static.tsx' 17 | import { RTMDataList } from '@app/ato/Products/DataList.tsx' 18 | import { Products } from '@app/ato/Products/Products' 19 | import { Certification } from '@app/lib/opencontrol' 20 | import { CompletionCharts } from '@app/ato/Charts/CompletionCharts' 21 | import { ComponentSSPTemplates } from '@app/ato/Documents/SSPTemplates' 22 | 23 | interface ProposeChangeProps { 24 | link: string; 25 | } 26 | 27 | interface ProposeChangeState { 28 | isOpen: boolean; 29 | } 30 | 31 | class ProposeChange extends React.PureComponent { 32 | constructor(props) { 33 | super(props); 34 | this.state = { 35 | isOpen: false 36 | }; 37 | this.onSelect = this.onSelect.bind(this); 38 | this.onToggle = this.onToggle.bind(this); 39 | 40 | } 41 | 42 | onSelect(event) { 43 | this.setState({ 44 | isOpen: !this.state.isOpen 45 | }); 46 | }; 47 | onToggle(isOpen) { 48 | this.setState({ 49 | isOpen 50 | }); 51 | }; 52 | 53 | render() { 54 | const { isOpen } = this.state; 55 | const appLauncherItems = [ 56 | 57 | Propose changes to this page 58 | , 59 | ]; 60 | return ( 61 |
62 | } /> 65 |
66 | ); 67 | } 68 | } 69 | 70 | interface ProductState { 71 | isLoading: boolean; 72 | productId: string; 73 | product: any; 74 | certifications: Certification[]; 75 | activeTabKey: string; 76 | }; 77 | 78 | class Product extends React.PureComponent { 79 | static texts(productId: string) { 80 | return ProductInfo[productId] ? ProductInfo[productId].texts : {}; 81 | } 82 | 83 | texts() { 84 | return Product.texts(this.state.productId); 85 | } 86 | 87 | renderMarkdown(textId) { 88 | const texts = this.texts(); 89 | const Element = texts[textId] as any; 90 | if (Element) { 91 | return 92 | 93 | 94 | } 95 | return ''; 96 | } 97 | 98 | showingMarkdown(): boolean { 99 | return this.state.activeTabKey != 'NIST-800-53' && this.state.activeTabKey != 'nist-800-53' && !this.showingCharts() && !this.showingSSPTemplates() 100 | } 101 | 102 | showingSSPTemplates(): boolean { 103 | return this.state.activeTabKey == 'ssp-templates' 104 | } 105 | 106 | showingCharts(): boolean { 107 | return this.state.activeTabKey == 'Charts' 108 | } 109 | 110 | urlForEditing(): string { 111 | if (this.showingMarkdown()) { 112 | return "https://github.com/RedHatGov/ocdb/edit/master/assets/src/app/assets/markdown/products/" + this.state.productId + "/" + this.state.activeTabKey + ".md" 113 | } else { 114 | return "https://github.com/ComplianceAsCode/redhat/tree/master/" + this.state.productId 115 | } 116 | } 117 | 118 | renderTabs() { 119 | if (this.showingMarkdown()) { 120 | const renderMarkdown = this.renderMarkdown; 121 | return renderMarkdown(this.state.activeTabKey); 122 | } else if (this.state.product != null && this.state.product.controls.length == 0) { 123 | return ( 124 | NIST-800-53 responses for {this.state.product.name} are not available in a form of open controls and/or oscal. 125 | ) 126 | } else if (this.showingSSPTemplates()) { 127 | return this.renderSSPTemplates() 128 | } else if (this.showingCharts()) { 129 | return this.renderCharts() 130 | } else { 131 | if (this.state.isLoading) { 132 | return 133 | } else { 134 | return ( 135 | 136 | 137 | {this.state.product['errors'].length == 0 ? 138 | '' : 139 | 140 | OpenControls Developer Information 141 | 142 | {this.state.product['errors'].map((function (error, i) { 143 | return {error}; 144 | }))} 145 | 146 | 147 | } 148 | Requirements Traceability Matrix 149 | 150 | 151 | 152 | ) 153 | } 154 | } 155 | } 156 | 157 | render() { 158 | if (this.state.productId == 'select') { 159 | return 160 | } 161 | 162 | // const Header = ( 163 | // 166 | // ); 167 | while (this.state.isLoading) { 168 | return ( 169 | 170 | 171 | 172 | 173 | 174 | 175 | ) 176 | } 177 | return ( 178 | }> 183 | 184 | 185 | 186 | {this.renderTabs()} 187 | 188 | 189 | 190 | ); 191 | } 192 | 193 | renderCharts() { 194 | return ( 195 | 196 | ) 197 | } 198 | 199 | renderSSPTemplates() { 200 | return ( 201 | 202 | ) 203 | } 204 | 205 | static getId(props) { 206 | return ProductIdOverride(props['computedMatch'].params.productId); 207 | } 208 | static getDerivedStateFromProps(props, state) { 209 | const productId = Product.getId(props); 210 | const activeTabKey = props['computedMatch'].params.tabId; 211 | if (state.productId != productId) { 212 | return { 213 | isLoading: true, 214 | productId: productId, 215 | product: null, 216 | activeTabKey: activeTabKey, 217 | } 218 | } 219 | if (state.activeTabKey != activeTabKey) { 220 | return { activeTabKey }; 221 | } 222 | return null; 223 | } 224 | componentDidUpdate() { 225 | if (this.state.isLoading && this.state.productId != 'select') { 226 | Api.componentControls(this.state.productId) 227 | .then(data => { 228 | this.setState({ product: data, isLoading: false }) 229 | }) 230 | } 231 | } 232 | 233 | constructor(props) { 234 | super(props); 235 | const productId = Product.getId(props); 236 | 237 | this.state = { 238 | isLoading: true, 239 | productId: productId, 240 | product: null, 241 | certifications: [], 242 | activeTabKey: props['computedMatch'].params.tabId, 243 | }; 244 | this.renderMarkdown = this.renderMarkdown.bind(this); 245 | this.componentDidUpdate = this.componentDidUpdate.bind(this); 246 | Api.certifications().then(data => this.setState({ certifications: data })) 247 | this.componentDidUpdate(); 248 | } 249 | } 250 | 251 | export { Product }; 252 | -------------------------------------------------------------------------------- /assets/src/app/ato/Products/Products.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Brand, CardBody, PageSection, PageSectionVariants } from '@patternfly/react-core'; 3 | import { 4 | Page, 5 | Gallery, 6 | GalleryItem, 7 | TextContent, 8 | Text, 9 | Card, 10 | CardTitle, 11 | CardFooter, 12 | CardHeader, 13 | CardHeaderMain, 14 | } from '@patternfly/react-core'; 15 | import { Spinner } from '@patternfly/react-core'; 16 | import { NavLink } from 'react-router-dom'; 17 | import { GetProductParamsFromUrl } from '@app/AppLayout/ProductSelector' 18 | import { ProductInfo } from '@app/ato/Products/Static.tsx' 19 | 20 | import * as Api from '@app/lib/api' 21 | import redhatLogo from '@app/assets/images/rh-hat.png'; 22 | 23 | const ProductGalleryItem: React.FunctionComponent = (props) => { 24 | var productId = props['product']['key']; 25 | var logo = (ProductInfo[productId] && ProductInfo[productId].image) || redhatLogo; 26 | return ( 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {/* {props['product']['name']} */} 36 | {props['product']['name']} 37 | { props.product.satisfies !== undefined ? 38 | {props['product']['satisfies'].length} controls defined 39 | : "" } 40 | 41 | 42 | 43 | ) 44 | }; 45 | 46 | class Products extends React.Component { 47 | render(){ 48 | const params = GetProductParamsFromUrl(); 49 | return ( 50 | 51 | 52 | 53 | Products 54 | Select a product to view its security-relevant documentation. 55 | 56 | 57 | 58 | 59 | 60 | { (this.state['isLoading'] ? : this.state['products'].map((function(object, i){ 61 | return (); 62 | })))} 63 | 64 | 65 | 66 | ); 67 | } 68 | 69 | constructor(props) { 70 | super(props); 71 | 72 | this.state = { 73 | isLoading: true, 74 | products: [] 75 | }; 76 | Api.components() 77 | .then(data => this.setState({products: data, isLoading: false})); 78 | } 79 | } 80 | 81 | export { Products }; 82 | 83 | -------------------------------------------------------------------------------- /assets/src/app/ato/Products/RTMDetail.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { PageSection, TextContent, Text, Tooltip, TooltipPosition } from '@patternfly/react-core'; 3 | import { InfoAltIcon } from '@patternfly/react-icons' 4 | import MDX from '@mdx-js/runtime' 5 | import { CustomControl } from '@app/lib/opencontrol' 6 | import { SatisfiesAccordion } from '@app/ato/Products/SatisfiesAccordion.tsx' 7 | 8 | interface RTMDetailProps { 9 | control: CustomControl; 10 | } 11 | 12 | const RTMDetail = React.memo((props: RTMDetailProps) => { 13 | const parsed = props.control.Key.split(')')[0].split(' ('); 14 | const key = parsed[0] 15 | const enhancement = parsed[1] 16 | var c = props.control; 17 | 18 | return ( 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 |
28 | {c.Key}: {c.Control.name} 29 | {c.Control.description} 30 | {c.Key}: What is the solution and how is it implemented? 31 |
32 | 33 |
34 | ); 35 | }) 36 | 37 | export { RTMDetail } 38 | -------------------------------------------------------------------------------- /assets/src/app/ato/Products/SatisfiesAccordion.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ExpandableSection, Text } from '@patternfly/react-core'; 3 | import MDX from '@mdx-js/runtime' 4 | import { Satisfies } from '@app/lib/opencontrol' 5 | 6 | interface CustomControlProps { 7 | satisfies?: Satisfies; 8 | } 9 | 10 | const SatisfiesAccordion = React.memo((props: CustomControlProps) => { 11 | if (props.satisfies == null || (props.satisfies.narrative.length == 1 && props.satisfies.narrative[0].text == '')) { 12 | return (Not available); 13 | } 14 | if (props.satisfies.narrative.length == 1 && props.satisfies.narrative[0].key == undefined) { 15 | return ({props.satisfies.narrative[0].text}) 16 | } 17 | 18 | const cKey = props.satisfies.control_key; 19 | return ( 20 | 21 | { props.satisfies.narrative.map(function(n, idx) { 22 | return ( 23 | 24 | {n.text} 25 |
26 |
27 | ) 28 | })} 29 |
30 | ) 31 | }) 32 | 33 | export { SatisfiesAccordion } 34 | -------------------------------------------------------------------------------- /assets/src/app/ato/Products/Static.tsx: -------------------------------------------------------------------------------- 1 | export const ProductIdOverridesMap: {[Identifier: string]: string} = { 2 | coreos4: 'coreos-4', 3 | idm: 'identity-management', 4 | ocp3: 'openshift-container-platform-3', 5 | osp13: 'openstack-platform-13', 6 | rhvh: 'virtualization-host', 7 | rhvm: 'virtualization-manager' 8 | } 9 | 10 | function ProductIdOverride(id) { 11 | // Previously our product content was published under different names. 12 | // If user refers to the product by old name, we fetch the new name first. 13 | return ProductIdOverridesMap[id] || id; 14 | } 15 | 16 | 17 | interface ProductText { 18 | name: string; 19 | text: any; 20 | } 21 | 22 | export interface ProductTemplate { 23 | image?: string; 24 | texts: {[Identifier: string]:ProductText}; 25 | }; 26 | 27 | const ProductInfo: {[Identifier: string]: ProductTemplate } = { 28 | 'ansible-tower': { 29 | image: require('@app/assets/images/rh-tower.png').default, 30 | texts: { 31 | 'Overview': require('@app/assets/markdown/products/ansible-tower/Overview.md').default, 32 | 'ICS-500-27': require('@app/assets/markdown/products/ansible-tower/ICS-500-27.md').default, 33 | 'SCAP': require('@app/assets/markdown/products/ansible-tower/SCAP.md').default, 34 | } 35 | }, 36 | 'coreos-4': { 37 | image: require('@app/assets/images/rh-coreos.png').default, 38 | texts: { 39 | 'Overview': require('@app/assets/markdown/products/coreos-4/Overview.md').default, 40 | 'SCAP': require('@app/assets/markdown/products/coreos-4/SCAP.md').default, 41 | } 42 | }, 43 | 'identity-management': { 44 | texts: { 45 | 'Overview': require('@app/assets/markdown/products/identity-management/Overview.md').default 46 | } 47 | }, 48 | insights: { 49 | texts: { 50 | 'Overview': require('@app/assets/markdown/products/insights/Overview.md').default 51 | } 52 | }, 53 | 'openshift-container-platform-3': { 54 | image: require('@app/assets/images/rh-openshift.png').default, 55 | texts: { 56 | 'Overview': require('@app/assets/markdown/products/openshift-container-platform-3/Overview.md').default, 57 | 'SCAP': require('@app/assets/markdown/products/openshift-container-platform-3/SCAP.md').default, 58 | } 59 | }, 60 | 'openshift-container-platform-4': { 61 | image: require('@app/assets/images/rh-openshift.png').default, 62 | texts: { 63 | 'Overview': require('@app/assets/markdown/products/openshift-container-platform-4/Overview.md').default, 64 | 'SCAP': require('@app/assets/markdown/products/openshift-container-platform-4/SCAP.md').default, 65 | } 66 | }, 67 | 'openshift-dedicated': { 68 | image: require('@app/assets/images/rh-openshift.png').default, 69 | texts: { 70 | 'Overview': require('@app/assets/markdown/products/openshift-dedicated/Overview.md').default 71 | } 72 | }, 73 | 'openstack-platform-13': { 74 | image: require('@app/assets/images/rh-openstack.png').default, 75 | texts: { 76 | 'Overview': require('@app/assets/markdown/products/openstack-platform-13/Overview.md').default, 77 | 'SCAP': require('@app/assets/markdown/products/openstack-platform-13/SCAP.md').default, 78 | } 79 | }, 80 | 'rhacm': { 81 | texts: { 82 | 'Overview': require('@app/assets/markdown/products/rhacm/Overview.md').default, 83 | } 84 | }, 85 | 'rhel-7': { 86 | image: require('@app/assets/images/rh-rhel.png').default, 87 | texts: { 88 | 'Overview': require('@app/assets/markdown/products/rhel-7/Overview.md').default, 89 | 'SCAP': require('@app/assets/markdown/products/rhel-7/SCAP.md').default, 90 | } 91 | }, 92 | 'rhel-8': { 93 | image: require('@app/assets/images/rh-rhel8.png').default, 94 | texts: { 95 | 'Overview': require('@app/assets/markdown/products/rhel-8/Overview.md').default, 96 | 'SCAP': require('@app/assets/markdown/products/rhel-8/SCAP.md').default, 97 | 'STIG': require('@app/assets/markdown/products/rhel-8/STIG.md').default, 98 | } 99 | }, 100 | 'virtualization-host': { 101 | image: require('@app/assets/images/rh-virtualization.png').default, 102 | texts: { 103 | 'SCAP': require('@app/assets/markdown/products/virtualization-host/SCAP.md').default, 104 | 'Overview': require('@app/assets/markdown/products/virtualization-host/Overview.md').default, 105 | } 106 | }, 107 | 'virtualization-manager': { 108 | image: require('@app/assets/images/rh-virtualization.png').default, 109 | texts: { 110 | 'Overview': require('@app/assets/markdown/products/virtualization-manager/Overview.md').default, 111 | } 112 | } 113 | }; 114 | 115 | export { ProductIdOverride, ProductInfo } 116 | -------------------------------------------------------------------------------- /assets/src/app/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import '@patternfly/react-core/dist/styles/base.css'; 3 | import { BrowserRouter as Router } from 'react-router-dom'; 4 | import { AppLayout } from '@app/AppLayout/AppLayout'; 5 | import { AppRoutes } from '@app/routes'; 6 | import DocumentTitle from 'react-document-title'; 7 | import '@app/app.css'; 8 | 9 | const App: React.FunctionComponent = () => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | }; 20 | 21 | export { App }; 22 | -------------------------------------------------------------------------------- /assets/src/app/lib/Memoize.tsx: -------------------------------------------------------------------------------- 1 | export const Memoize = (fn) => { 2 | let cache = {}; 3 | return (...args) => { 4 | let n = args[0]; // just taking one argument here 5 | if (n in cache) { 6 | return cache[n]; 7 | } 8 | else { 9 | let result = fn(n); 10 | cache[n] = result; 11 | return result; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /assets/src/app/lib/api.tsx: -------------------------------------------------------------------------------- 1 | function memoize(method) { 2 | let cache = {}; 3 | return async function(...argum) { 4 | let args = JSON.stringify(argum); 5 | cache[args] = cache[args] || method.apply(undefined, argum); 6 | return cache[args]; 7 | }; 8 | } 9 | 10 | export var components = memoize(async function components() { 11 | return fetch('/api/v1/components').then(response => response.json()).then(addExtraProducts) 12 | }); 13 | 14 | const extraProducts = [ 15 | ]; 16 | 17 | function addExtraProducts(products) { 18 | return new Promise( 19 | function(resolve, reject) { 20 | resolve(extraProducts.concat(products).sort( 21 | function(a, b){ 22 | return a['name'] < b['name'] ? -1 : 1 23 | })) 24 | } 25 | ) 26 | } 27 | 28 | export var componentControls = memoize(async function(componentId: string) { 29 | return fetch('/api/v1/components/' + componentId + '/controls') 30 | .then(response => response.json()) 31 | .then((data) => { 32 | const nist80053 = data['controls']['NIST-800-53']; 33 | data['controls'] = Array.prototype.concat.apply([], Object.keys(nist80053).map(function(k, _) { return nist80053[k]; })); 34 | return data 35 | }) 36 | }); 37 | 38 | export var certifications = memoize(async function() { 39 | return fetch('/api/v1/certifications') 40 | .then(response => response.json()) 41 | .then(data => { 42 | return Array.prototype.concat.apply([], Object.keys(data).map(function(k, _) { 43 | return {Key: k, 44 | Controls: data[k].Controls['NIST-800-53']} 45 | })) 46 | }) 47 | }) 48 | 49 | export var statistics = memoize(async function(componentId: string) { 50 | return fetch('/api/v1/components/' + componentId + '/statistics') 51 | .then(response => response.json()) 52 | }) 53 | -------------------------------------------------------------------------------- /assets/src/app/lib/csv.tsx: -------------------------------------------------------------------------------- 1 | export function ServeCSV(filename, data) { 2 | var blob = new Blob([data], {type: 'text/csv'}); 3 | if (false) { 4 | window.navigator.msSaveBlob(blob, filename); 5 | } 6 | else{ 7 | var elem = window.document.createElement('a'); 8 | elem.href = window.URL.createObjectURL(blob); 9 | elem.download = filename; 10 | document.body.appendChild(elem); 11 | elem.click(); 12 | document.body.removeChild(elem); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /assets/src/app/lib/markdown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { MDXProvider } from '@mdx-js/react' 3 | import { TextContent } from '@patternfly/react-core'; 4 | 5 | const pfTable = (props) => 6 | 7 | const pfMapping = { 8 | table: pfTable, 9 | } 10 | 11 | const Markdown: React.FunctionComponent = (props) => { 12 | return ( 13 | 14 | 15 | {props.children} 16 | 17 | 18 | ) 19 | } 20 | 21 | export { Markdown }; 22 | -------------------------------------------------------------------------------- /assets/src/app/lib/opencontrol.tsx: -------------------------------------------------------------------------------- 1 | interface Narrative { 2 | key?: string, 3 | text: string 4 | } 5 | 6 | export interface Satisfies { 7 | control_key: string; 8 | narrative: Narrative[]; 9 | implementation_status: string; 10 | } 11 | 12 | interface Control { 13 | name: string, 14 | description: string, 15 | } 16 | 17 | export interface CustomControl { 18 | Key: string, 19 | Control: Control, 20 | Satisfies?: Satisfies, 21 | } 22 | 23 | export interface Certification { 24 | Key: string, 25 | Controls: string[] 26 | } 27 | 28 | export function OpenControlToCSV(list: CustomControl[]) { 29 | var result = "NIST-800-53,Name,Description,Implementation Status,Control Response\n" 30 | list.map((c) => { 31 | const status = c.Satisfies ? c.Satisfies.implementation_status : "unknown" 32 | const response = c.Satisfies ? 33 | (Array.isArray(c.Satisfies.narrative) ? 34 | c.Satisfies.narrative.map((n) => { return n.text + '\n'}).reduce((a,b) => a+b) : 35 | c.Satisfies.narrative 36 | ) : 37 | "" 38 | const line = c.Key + "," 39 | + c.Control.name + "," 40 | + escape(c.Control.description) + "," 41 | + status + "," 42 | + escape(response) + "\n" 43 | result += line 44 | }) 45 | return result 46 | } 47 | 48 | function escape(field) { 49 | return '"' + field.replace('"', '""') + '"' 50 | } 51 | -------------------------------------------------------------------------------- /assets/src/app/lib/querystring.tsx: -------------------------------------------------------------------------------- 1 | import queryString from 'query-string' 2 | 3 | export function Parse() { 4 | return queryString.parse(window.location.search) 5 | } 6 | 7 | export function Set(hash) { 8 | var qs = queryString.stringify(hash) 9 | if (qs != "") { 10 | qs = "?" + qs 11 | } 12 | history.pushState({page: 1}, "title 1", window.location.pathname + qs) 13 | } 14 | -------------------------------------------------------------------------------- /assets/src/app/routes.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Route, RouteComponentProps, Switch, Redirect } from 'react-router-dom'; 3 | import { accessibleRouteChangeHandler } from '@app/utils/utils'; 4 | import { ATODocuments } from '@app/ato/Documents/Overview'; 5 | import { ATOTrainingPlan, ATOVulnerabilityManagementPlan, ComponentSSPTemplates } from '@app/ato/Documents/Documents'; 6 | import { Product } from '@app/ato/Products/Product'; 7 | import { Products } from '@app/ato/Products/Products'; 8 | import { GettingStarted } from '@app/ato/GettingStarted'; 9 | import { NotFound } from '@app/NotFound/NotFound'; 10 | import DocumentTitle from 'react-document-title'; 11 | import { LastLocationProvider, useLastLocation } from 'react-router-last-location'; 12 | import { ProductIdOverridesMap } from '@app/ato/Products/Static' 13 | let routeFocusTimer: number; 14 | 15 | 16 | const RouteWithTitleUpdates = ({ component: Component, isAsync = false, title, ...rest }) => { 17 | const lastNavigation = useLastLocation(); 18 | 19 | function routeWithTitle(routeProps: RouteComponentProps) { 20 | return ( 21 | 22 | 23 | 24 | ); 25 | } 26 | 27 | React.useEffect(() => { 28 | if (!isAsync && lastNavigation !== null) { 29 | routeFocusTimer = accessibleRouteChangeHandler(); 30 | } 31 | return () => { 32 | clearTimeout(routeFocusTimer); 33 | }; 34 | }, []); 35 | 36 | return ; 37 | }; 38 | 39 | export interface IAppRoute { 40 | label: string; 41 | component: React.ComponentType> | React.ComponentType; 42 | icon: any; 43 | exact?: boolean; 44 | path: string; 45 | title: string; 46 | isAsync?: boolean; 47 | } 48 | 49 | const routes: IAppRoute[] = [ 50 | { 51 | component: GettingStarted, 52 | exact: true, 53 | icon: null, 54 | label: 'Getting Started', 55 | path: '/', 56 | title: 'Getting Started', 57 | }, 58 | { 59 | component: GettingStarted, 60 | exact: true, 61 | icon: null, 62 | label: 'Getting Started', 63 | path: '/ato/getting_started', 64 | title: 'Getting Started', 65 | }, 66 | { 67 | component: ATODocuments, 68 | exact: true, 69 | icon: null, 70 | label: 'ATO Documents', 71 | path: '/ato/documents', 72 | title: 'ATO Documents', 73 | }, 74 | { 75 | component: ATOVulnerabilityManagementPlan, 76 | exact: true, 77 | icon: null, 78 | label: 'Vulnerability Management Plan', 79 | path: '/ato/documents/vulnerability-management-plan', 80 | title: 'Vulnerability Management Plan', 81 | }, 82 | { 83 | component: ATOTrainingPlan, 84 | exact: true, 85 | icon: null, 86 | label: 'Security Awareness and Training Plan', 87 | path: '/ato/documents/security-awareness-and-training-plan', 88 | title: 'Security Awareness and Training Plan', 89 | }, 90 | { 91 | component: Products, 92 | exact: true, 93 | icon: null, 94 | isAsync: true, 95 | label: 'Products', 96 | path: '/ato/products', 97 | title: 'Product Documents' 98 | }, 99 | { 100 | component: Product, 101 | exact: true, 102 | icon: null, 103 | isAsync: true, 104 | label: 'Product', 105 | path: '/ato/products/:productId/:tabId?', 106 | title: 'Product Document', 107 | }, 108 | { 109 | component: Product, 110 | exact: true, 111 | icon: null, 112 | isAsync: true, 113 | label: 'Product', 114 | path: '/product-documents/:productId/:tabId/:garbage/', // Maintain the same links that lead to the old site. 115 | title: 'Product Document', 116 | }, 117 | ]; 118 | 119 | const AppRoutes = () => ( 120 | 121 | 122 | {routes.map(({ path, exact, component, title, isAsync, icon }, idx) => ( 123 | 132 | ))} 133 | 134 | { 135 | Object.keys(ProductIdOverridesMap).map((function(key, i) { 136 | return ( 137 | } 139 | /> 140 | ) 141 | })) 142 | } 143 | 144 | 145 | 146 | ); 147 | 148 | export { AppRoutes, routes }; 149 | -------------------------------------------------------------------------------- /assets/src/app/utils/utils.ts: -------------------------------------------------------------------------------- 1 | export function accessibleRouteChangeHandler() { 2 | return window.setTimeout(() => { 3 | const mainContainer = document.getElementById('primary-app-container'); 4 | if (mainContainer) { 5 | mainContainer.focus(); 6 | } 7 | }, 50); 8 | } 9 | -------------------------------------------------------------------------------- /assets/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import { App } from '@app/index'; 4 | 5 | /* 6 | if (process.env.NODE_ENV !== "production") { 7 | // tslint:disable-next-line 8 | const axe = require("react-axe"); 9 | axe(React, ReactDOM, 1000); 10 | } 11 | */ 12 | 13 | window.onload = function(){ 14 | ReactDOM.render(, document.getElementById("root") as HTMLElement); 15 | }; 16 | -------------------------------------------------------------------------------- /assets/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.png'; 2 | declare module '*.jpg'; 3 | declare module '*.jpeg'; 4 | declare module '*.gif'; 5 | declare module '*.svg'; 6 | declare module '*.css'; 7 | declare module '*.wav'; 8 | declare module '*.mp3'; 9 | declare module '*.m4a'; 10 | declare module '*.rdf'; 11 | declare module '*.ttl'; 12 | declare module '*.pdf'; 13 | declare module 'react-document-title'; 14 | declare module '*.md' { 15 | let MDXComponent: (props: any) => JSX.Element 16 | export default MDXComponent 17 | } 18 | -------------------------------------------------------------------------------- /config/buffalo-app.toml: -------------------------------------------------------------------------------- 1 | name = "ocdb" 2 | bin = "bin/ocdb" 3 | vcs = "git" 4 | with_pop = false 5 | with_sqlite = false 6 | with_dep = false 7 | with_webpack = true 8 | with_nodejs = true 9 | with_yarn = true 10 | with_docker = true 11 | with_grifts = true 12 | as_web = true 13 | as_api = false 14 | -------------------------------------------------------------------------------- /config/buffalo-plugins.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/config/buffalo-plugins.toml -------------------------------------------------------------------------------- /database.yml: -------------------------------------------------------------------------------- 1 | --- 2 | development: 3 | dialect: postgres 4 | database: ocdb_development 5 | user: postgres 6 | password: postgres 7 | host: 127.0.0.1 8 | pool: 5 9 | 10 | test: 11 | url: {{envOr "TEST_DATABASE_URL" "postgres://postgres:postgres@127.0.0.1:5432/ocdb_test?sslmode=disable"}} 12 | 13 | production: 14 | url: {{envOr "DATABASE_URL" "postgres://postgres:postgres@127.0.0.1:5432/ocdb_production?sslmode=disable"}} 15 | -------------------------------------------------------------------------------- /fixtures/sample.toml: -------------------------------------------------------------------------------- 1 | [[scenario]] 2 | name = "lots of widgets" 3 | 4 | [[scenario.table]] 5 | name = "widgets" 6 | 7 | [[scenario.table.row]] 8 | id = "<%= uuidNamed("widget") %>" 9 | name = "This is widget #1" 10 | body = "some widget body" 11 | created_at = "<%= now() %>" 12 | updated_at = "<%= now() %>" 13 | 14 | [[scenario.table.row]] 15 | id = "<%= uuid() %>" 16 | name = "This is widget #2" 17 | body = "some widget body" 18 | created_at = "<%= now() %>" 19 | updated_at = "<%= now() %>" 20 | 21 | [[scenario.table]] 22 | name = "users" 23 | 24 | [[scenario.table.row]] 25 | id = "<%= uuid() %>" 26 | name = "Mark Bates" 27 | admin = true 28 | age = 41 29 | widget_id = "<%= uuidNamed("widget") %>" 30 | created_at = "<%= now() %>" 31 | updated_at = "<%= now() %>" 32 | 33 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/RedHatGov/ocdb 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/Masterminds/semver/v3 v3.1.1 // indirect 7 | github.com/fatih/color v1.10.0 // indirect 8 | github.com/gobuffalo/buffalo v0.16.19 9 | github.com/gobuffalo/envy v1.9.0 10 | github.com/gobuffalo/fizz v1.13.0 // indirect 11 | github.com/gobuffalo/mw-csrf v1.0.0 12 | github.com/gobuffalo/mw-i18n v1.1.0 13 | github.com/gobuffalo/mw-paramlogger v1.0.0 14 | github.com/gobuffalo/nulls v0.4.0 // indirect 15 | github.com/gobuffalo/packr/v2 v2.8.1 16 | github.com/gobuffalo/pop/v5 v5.3.1 // indirect 17 | github.com/gobuffalo/suite v2.8.2+incompatible 18 | github.com/gobuffalo/validate/v3 v3.3.0 // indirect 19 | github.com/gocomply/scap v0.1.1 // indirect 20 | github.com/gofrs/uuid v4.0.0+incompatible // indirect 21 | github.com/google/go-cmp v0.5.2 // indirect 22 | github.com/gorilla/handlers v1.5.1 // indirect 23 | github.com/gorilla/mux v1.8.0 // indirect 24 | github.com/gorilla/sessions v1.2.1 // indirect 25 | github.com/jackc/pgproto3/v2 v2.0.7 // indirect 26 | github.com/jackc/pgx/v4 v4.10.1 // indirect 27 | github.com/karrick/godirwalk v1.16.1 // indirect 28 | github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect 29 | github.com/lib/pq v1.8.0 // indirect 30 | github.com/markbates/grift v1.5.0 31 | github.com/microcosm-cc/bluemonday v1.0.4 // indirect 32 | github.com/monoculum/formam v0.0.0-20200923020755-6f187e4ffe27 // indirect 33 | github.com/opencontrol/compliance-masonry v1.1.7-0.20200827173050-70bb3370161e 34 | github.com/pelletier/go-toml v1.8.1 // indirect 35 | github.com/rogpeppe/go-internal v1.6.2 // indirect 36 | github.com/rolieup/golie v0.2.1 37 | github.com/sirupsen/logrus v1.7.0 // indirect 38 | github.com/spf13/cobra v1.1.1 // indirect 39 | github.com/stretchr/testify v1.6.1 // indirect 40 | golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect 41 | golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect 42 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect 43 | golang.org/x/sys v0.0.0-20210105210732-16f7687f5001 // indirect 44 | golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect 45 | golang.org/x/text v0.3.5 // indirect 46 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 47 | gopkg.in/yaml.v2 v2.4.0 // indirect 48 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect 49 | vbom.ml/util v0.0.3 // indirect 50 | ) 51 | 52 | replace ( 53 | github.com/codegangsta/cli => github.com/urfave/cli v1.18.1-0.20160712171436-3a5216227e14 54 | github.com/go-utils/ufs => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/go-utils/ufs 55 | github.com/go-utils/ugo => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/go-utils/ugo 56 | github.com/go-utils/uslice => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/go-utils/uslice 57 | github.com/go-utils/ustr => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/go-utils/ustr 58 | github.com/opencontrol/compliance-masonry/commands/docs => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/opencontrol/compliance-masonry/commands/docs 59 | github.com/opencontrol/compliance-masonry/config => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/opencontrol/compliance-masonry/config 60 | github.com/opencontrol/compliance-masonry/models => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/opencontrol/compliance-masonry/models 61 | github.com/opencontrol/fedramp-templater => ./vendor/github.com/opencontrol/fedramp-templater 62 | gopkg.in/fatih/set.v0 => ./vendor/github.com/opencontrol/fedramp-templater/vendor/github.com/opencontrol/compliance-masonry/vendor/gopkg.in/fatih/set.v0 63 | vbom.ml/util => github.com/fvbommel/util v0.0.0-20180919145318-efcd4e0f9787 64 | ) 65 | -------------------------------------------------------------------------------- /grifts/db.go: -------------------------------------------------------------------------------- 1 | package grifts 2 | 3 | import ( 4 | "github.com/markbates/grift/grift" 5 | ) 6 | 7 | var _ = grift.Namespace("db", func() { 8 | 9 | grift.Desc("seed", "Seeds a database") 10 | grift.Add("seed", func(c *grift.Context) error { 11 | // Add DB seeding stuff here 12 | return nil 13 | }) 14 | 15 | }) 16 | -------------------------------------------------------------------------------- /grifts/init.go: -------------------------------------------------------------------------------- 1 | package grifts 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo" 5 | "github.com/RedHatGov/ocdb/actions" 6 | ) 7 | 8 | func init() { 9 | buffalo.Grifts(actions.App()) 10 | } 11 | -------------------------------------------------------------------------------- /inflections.json: -------------------------------------------------------------------------------- 1 | { 2 | "singular": "plural" 3 | } 4 | -------------------------------------------------------------------------------- /locales/all.en-us.yaml: -------------------------------------------------------------------------------- 1 | # For more information on using i18n see: https://github.com/nicksnyder/go-i18n 2 | - id: welcome_greeting 3 | translation: "OpenControl Database" 4 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/RedHatGov/ocdb/actions" 7 | ) 8 | 9 | // main is the starting point for your Buffalo application. 10 | // You can feel free and add to this `main` method, change 11 | // what it does, etc... 12 | // All we ask is that, at some point, you make sure to 13 | // call `app.Serve()`, unless you don't want to start your 14 | // application that is. :) 15 | func main() { 16 | app := actions.App() 17 | if err := app.Serve(); err != nil { 18 | log.Fatal(err) 19 | } 20 | } 21 | 22 | /* 23 | # Notes about `main.go` 24 | 25 | ## SSL Support 26 | 27 | We recommend placing your application behind a proxy, such as 28 | Apache or Nginx and letting them do the SSL heavy lifting 29 | for you. https://gobuffalo.io/en/docs/proxy 30 | 31 | ## Buffalo Build 32 | 33 | When `buffalo build` is run to compile your binary, this `main` 34 | function will be at the heart of that binary. It is expected 35 | that your `main` function will start your application using 36 | the `app.Serve()` method. 37 | 38 | */ 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "buffalo", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "dev": "webpack --watch", 8 | "build": "webpack -p --progress" 9 | }, 10 | "repository": "github.com/gobuffalo/buffalo", 11 | "dependencies": { 12 | "@babel/preset-react": "^7.10.4", 13 | "@mdx-js/loader": "^1.6.16", 14 | "@mdx-js/runtime": "^1.6.16", 15 | "@patternfly/react-charts": "^6.9.6", 16 | "@patternfly/react-core": "^4.47.0", 17 | "@patternfly/react-table": "^4.16.7", 18 | "@types/jest": "^26.0.13", 19 | "@types/react": "^16.9.49", 20 | "@types/react-dom": "^16.9.8", 21 | "@types/react-router-dom": "^5.1.5", 22 | "bootstrap": "4.5.2", 23 | "enzyme": "^3.10.0", 24 | "jquery": "~3.5.1", 25 | "jquery-ujs": "~1.2.2", 26 | "popper.js": "^1.14.4", 27 | "prop-types": "^15.7.2", 28 | "react": "^16.13.1", 29 | "react-axe": "^3.5.3", 30 | "react-document-title": "^2.0.3", 31 | "react-dom": "^16.13.1", 32 | "react-router-dom": "^5.2.0", 33 | "react-router-last-location": "^2.0.1", 34 | "ts-loader": "^8.0.3", 35 | "tsconfig-paths-webpack-plugin": "^3.3.0", 36 | "typescript": "^4.0.2", 37 | "yarn": "^1.22.5" 38 | }, 39 | "devDependencies": { 40 | "@babel/cli": "^7.11.6", 41 | "@babel/core": "^7.11.6", 42 | "@babel/preset-env": "^7.11.5", 43 | "babel-loader": "^8.1.0", 44 | "copy-webpack-plugin": "~6.1.0", 45 | "css-loader": "~4.2.2", 46 | "expose-loader": "~1.0.0", 47 | "file-loader": "~6.1.0", 48 | "mini-css-extract-plugin": "^0.11.0", 49 | "node-sass": "~4.14.1", 50 | "sass-loader": "~10.0.2", 51 | "style-loader": "~1.2.1", 52 | "uglifyjs-webpack-plugin": "~2.2.0", 53 | "url-loader": "~4.1.0", 54 | "webpack": "~4.44.1", 55 | "webpack-clean-obsolete-chunks": "^0.4.0", 56 | "webpack-cli": "3.3.12", 57 | "webpack-livereload-plugin": "2.3.0", 58 | "webpack-manifest-plugin": "~2.2.0" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /pkg/backend/job/job.go: -------------------------------------------------------------------------------- 1 | package job 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/pkg/utils" 5 | "github.com/gobuffalo/buffalo/worker" 6 | "time" 7 | ) 8 | 9 | type JobFn func() error 10 | 11 | type Job struct { 12 | Name string 13 | Fn JobFn `json:"-"` 14 | Period time.Duration 15 | DelayedStart time.Duration 16 | LastStart time.Time 17 | LastSuccess time.Time 18 | LastError string 19 | ErrorCount uint 20 | } 21 | 22 | func (job *Job) SetUpIn(w worker.Worker) { 23 | err := w.Register(job.Name, func(args worker.Args) error { 24 | job.reschedule(w, job.Period) 25 | return job.run() 26 | }) 27 | if err != nil { 28 | utils.Log.Fatalf("Could not register job: %v", err) 29 | } 30 | job.reschedule(w, job.DelayedStart+time.Second) 31 | } 32 | 33 | func (job *Job) reschedule(w worker.Worker, period time.Duration) { 34 | err := w.PerformIn(worker.Job{ 35 | Queue: "masonry", 36 | Handler: job.Name, 37 | }, period) 38 | if err != nil { 39 | utils.Log.Errorf("Could not reschedule job %s: %v", job.Name, err) 40 | } 41 | } 42 | 43 | func (job *Job) run() error { 44 | job.LastStart = time.Now() 45 | 46 | err := job.Fn() 47 | if err != nil { 48 | job.LastError = err.Error() 49 | job.ErrorCount += 1 50 | if job.ErrorCount < 16 { 51 | utils.Log.Errorf("Job '%s' Failed: %s. Re-trying", job.Name, job.LastError) 52 | return job.run() 53 | } 54 | } else { 55 | job.LastError = "" 56 | job.LastSuccess = time.Now() 57 | job.ErrorCount = 0 58 | } 59 | return err 60 | } 61 | -------------------------------------------------------------------------------- /pkg/cac/acquire.go: -------------------------------------------------------------------------------- 1 | package cac 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "github.com/RedHatGov/ocdb/pkg/git" 7 | "github.com/RedHatGov/ocdb/pkg/utils" 8 | 9 | "os/exec" 10 | "sync" 11 | ) 12 | 13 | var mux sync.Mutex 14 | 15 | const ( 16 | gitCache = "/var/tmp/ocdb/ComplianceAsCode.content" 17 | buildCache = gitCache + "/build/" 18 | installCache = "/var/tmp/ocdb/ComplianceAsCode.content_install/" 19 | installScapCache = installCache + "share/xml/scap/ssg/content/" 20 | ) 21 | 22 | // Refresh function refreshes masonry data 23 | func Refresh() error { 24 | mux.Lock() 25 | defer mux.Unlock() 26 | err := git.PullOrClone(gitCache, "https://github.com/ComplianceAsCode/content", nil) 27 | if err != nil { 28 | return err 29 | } 30 | err = cmake() 31 | if err != nil { 32 | return err 33 | } 34 | err = make() 35 | if err != nil { 36 | return err 37 | } 38 | err = buildRolieFeed() 39 | if err != nil { 40 | return err 41 | } 42 | return makeSrgCsv() 43 | } 44 | 45 | func make() error { 46 | makeCmd := exec.Command("make", "install") 47 | makeCmd.Dir = buildCache 48 | logWriter := utils.LogWriter{} 49 | makeCmd.Stdout = logWriter 50 | makeCmd.Stderr = logWriter 51 | 52 | err := makeCmd.Run() 53 | if err != nil { 54 | return fmt.Errorf("Error running make: %v", err) 55 | } 56 | return nil 57 | } 58 | 59 | func cmake() error { 60 | cmakeParams := []string{ 61 | "-DSSG_PRODUCT_DEFAULT:BOOLEAN=FALSE", 62 | "-DSSG_PRODUCT_RHEL7:BOOLEAN=TRUE", 63 | "-DSSG_PRODUCT_RHEL8:BOOLEAN=TRUE", 64 | "-DSSG_PRODUCT_OCP4:BOOLEAN=TRUE", 65 | "-DSSG_PRODUCT_RHOSP13:BOOLEAN=TRUE", 66 | "-DSSG_PRODUCT_RHCOS4:BOOLEAN=TRUE", 67 | "-DSSG_PRODUCT_FIREFOX:BOOLEAN=TRUE", 68 | "-DCMAKE_BUILD_TYPE=Debug", 69 | "-DSSG_CENTOS_DERIVATIVES_ENABLED:BOOL=OFF", 70 | "-DSSG_SCIENTIFIC_LINUX_DERIVATIVES_ENABLED:BOOL=OFF", 71 | "-DSSG_OVAL_SCHEMATRON_VALIDATION_ENABLED=FALSE", 72 | "-DCMAKE_INSTALL_PREFIX=" + installCache, 73 | "../", 74 | } 75 | cmakeCmd := exec.Command("cmake", cmakeParams...) 76 | cmakeCmd.Dir = buildCache 77 | cmakeCmdErr := &bytes.Buffer{} 78 | cmakeCmd.Stdout = &utils.LogWriter{} 79 | cmakeCmd.Stderr = cmakeCmdErr 80 | 81 | err := cmakeCmd.Run() 82 | if err != nil || cmakeCmdErr.Len() > 0 { 83 | return fmt.Errorf("Error running cmake: %v, stderr was: %s", err, cmakeCmdErr.String()) 84 | } 85 | return nil 86 | } 87 | -------------------------------------------------------------------------------- /pkg/cac/csv.go: -------------------------------------------------------------------------------- 1 | package cac 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "github.com/RedHatGov/ocdb/pkg/static" 7 | "github.com/RedHatGov/ocdb/pkg/utils" 8 | "io/ioutil" 9 | 10 | "os/exec" 11 | ) 12 | 13 | const xsltFilename = "srg-to-csv.xslt" 14 | 15 | func makeSrgCsv() error { 16 | err := unbundleXslt() 17 | if err != nil { 18 | return err 19 | } 20 | err = srgToCsv("rhel8") 21 | if err != nil { 22 | return err 23 | } 24 | return srgToCsv("rhel7") 25 | } 26 | 27 | func srgToCsv(product string) error { 28 | cmd := exec.Command("/usr/bin/xsltproc", 29 | "--stringparam", "map-to-items", product+"/xccdf-linked-srg-overlay.xml", 30 | "--stringparam", "ocil-document", product+"/ocil-linked.xml", 31 | "--output", "tables/table-"+product+"-srgmap-flat.csv", 32 | xsltFilename, 33 | "../shared/references/disa-os-srg-v1r6.xml") 34 | cmd.Dir = buildCache 35 | cmdErr := &bytes.Buffer{} 36 | cmd.Stdout = &utils.LogWriter{} 37 | cmd.Stderr = cmdErr 38 | 39 | err := cmd.Run() 40 | if err != nil || cmdErr.Len() > 0 { 41 | return fmt.Errorf("Error running xsltproc: %v, stderr was: %s", err, cmdErr.String()) 42 | } 43 | return nil 44 | } 45 | 46 | func unbundleXslt() error { 47 | xsltBytes, err := static.AssetsBox.Find("/" + xsltFilename) 48 | if err != nil { 49 | return fmt.Errorf("Assets pack does not contain %s: %v", xsltFilename, err) 50 | } 51 | return ioutil.WriteFile(buildCache+xsltFilename, xsltBytes, 0600) 52 | } 53 | -------------------------------------------------------------------------------- /pkg/cac/http.go: -------------------------------------------------------------------------------- 1 | package cac 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | func BuildFiles() http.FileSystem { 8 | return http.Dir(buildCache) 9 | } 10 | 11 | func InstalledScapFiles() http.FileSystem { 12 | return http.Dir(installScapCache) 13 | } 14 | -------------------------------------------------------------------------------- /pkg/cac/rolie.go: -------------------------------------------------------------------------------- 1 | package cac 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/pkg/utils" 5 | "github.com/rolieup/golie/pkg/rolie" 6 | ) 7 | 8 | func buildRolieFeed() error { 9 | utils.Log.Debug("Re-building ROLIE feed.") 10 | builder := rolie.Builder{ 11 | ID: "compliance-as-code", 12 | Title: "Rolie feed for the latest SCAP files by ComplianceAsCode", 13 | RootURI: "https://atopathways.redhatgov.io/compliance-as-code/scap/", 14 | DirectoryPath: installScapCache, 15 | } 16 | return builder.New() 17 | 18 | } 19 | -------------------------------------------------------------------------------- /pkg/cac_oscal/acquire.go: -------------------------------------------------------------------------------- 1 | package cac_oscal 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | "sync" 7 | 8 | "github.com/RedHatGov/ocdb/pkg/git" 9 | "github.com/RedHatGov/ocdb/pkg/utils" 10 | ) 11 | 12 | var mux sync.Mutex 13 | 14 | const ( 15 | gitCache = "/var/tmp/ocdb/ComplianceAsCode.oscal" 16 | docxCache = gitCache + "/docx" 17 | ) 18 | 19 | // Refresh function refreshes masonry data 20 | func Refresh() error { 21 | mux.Lock() 22 | defer mux.Unlock() 23 | err := git.PullOrClone(gitCache, "https://github.com/ComplianceAsCode/oscal", nil) 24 | if err != nil { 25 | return err 26 | } 27 | return make("docx") 28 | } 29 | 30 | func make(target string) error { 31 | makeCmd := exec.Command("make", target) 32 | makeCmd.Dir = gitCache 33 | logWriter := utils.LogWriter{} 34 | makeCmd.Stdout = logWriter 35 | makeCmd.Stderr = logWriter 36 | err := makeCmd.Run() 37 | if err != nil { 38 | return fmt.Errorf("Error running make: %v", err) 39 | } 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /pkg/cac_oscal/fedramp.go: -------------------------------------------------------------------------------- 1 | package cac_oscal 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func FedrampDocument(componentId, level, format string) (io.ReadCloser, error) { 10 | path := fedrampPath(componentId, level, format) 11 | switch format { 12 | case "docx": 13 | file, err := os.Open(path) 14 | if err != nil { 15 | err = buildFedrampDocx(componentId, level) 16 | if err != nil { 17 | return nil, err 18 | } 19 | file, err = os.Open(path) 20 | } 21 | return file, err 22 | case "xml": 23 | return os.Open(path) 24 | case "json": 25 | return os.Open(path) 26 | default: 27 | return nil, fmt.Errorf("Unsupported FedRAMP formatting: %s", format) 28 | } 29 | } 30 | 31 | func buildFedrampDocx(componentId, level string) error { 32 | return make("docx/" + fedrampFilename(componentId, level, "docx")) 33 | } 34 | 35 | func fedrampPath(componentId, level, format string) string { 36 | return fmt.Sprintf("%s/%s/%s", gitCache, format, fedrampFilename(componentId, level, format)) 37 | } 38 | 39 | func fedrampFilename(componentId, level, format string) string { 40 | return fmt.Sprintf("%s-fedramp-%s.%s", componentId, level, format) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/git/easy.go: -------------------------------------------------------------------------------- 1 | package git 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "github.com/RedHatGov/ocdb/pkg/utils" 7 | "os" 8 | "os/exec" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func Clone(gitRepo, directory string, since *time.Time) error { 14 | gitCmd := exec.Command("git", "clone", "--depth", "1", gitRepo, directory) 15 | if since != nil { 16 | gitCmd = exec.Command("git", "clone", "--shallow-since", since.AddDate(0, 0, -1).String(), gitRepo, directory) 17 | } 18 | logWriter := utils.LogWriter{} 19 | gitCmd.Stdout = &logWriter 20 | gitCmd.Stderr = &logWriter 21 | 22 | err := gitCmd.Run() 23 | if err != nil { 24 | return fmt.Errorf("Error running git clone %s: %v", gitRepo, err) 25 | } 26 | return nil 27 | } 28 | 29 | func Pull(directory string) error { 30 | gitCmd := exec.Command("git", "pull") 31 | gitCmd.Dir = directory 32 | logWriter := utils.LogWriter{} 33 | gitCmd.Stdout = &logWriter 34 | gitCmd.Stderr = &logWriter 35 | 36 | err := gitCmd.Run() 37 | if err != nil { 38 | return fmt.Errorf("Error running git pull in %s: %v", directory, err) 39 | } 40 | return nil 41 | } 42 | 43 | func PullOrClone(directory, gitRepo string, since *time.Time) error { 44 | if stat, err := os.Stat(directory); err == nil && stat.IsDir() { 45 | return Pull(directory) 46 | } 47 | return Clone(gitRepo, directory, since) 48 | } 49 | 50 | func LastCommitBy(directory string, date time.Time) (string, error) { 51 | command := fmt.Sprintf("git log --pretty=format:\"%%H\" --until=\"%s\" | head -n 1", date) 52 | 53 | gitCmd := exec.Command("bash", "-c", command) 54 | gitCmd.Dir = directory 55 | stdout := bytes.Buffer{} 56 | stderr := bytes.Buffer{} 57 | gitCmd.Stdout = &stdout 58 | gitCmd.Stderr = &stderr 59 | 60 | err := gitCmd.Run() 61 | if err != nil || stderr.Len() > 0 { 62 | return "", fmt.Errorf("Error running git log: %v; stderr: %s", err, stderr.String()) 63 | } 64 | 65 | return strings.Replace(stdout.String(), "\n", "", 1), nil 66 | } 67 | -------------------------------------------------------------------------------- /pkg/masonry/acquire.go: -------------------------------------------------------------------------------- 1 | package masonry 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/opencontrol/compliance-masonry/pkg/cli/get/resources" 7 | "github.com/opencontrol/compliance-masonry/pkg/lib" 8 | "github.com/opencontrol/compliance-masonry/pkg/lib/common" 9 | "github.com/opencontrol/compliance-masonry/pkg/lib/opencontrol" 10 | "github.com/opencontrol/compliance-masonry/pkg/lib/opencontrol/versions/1.0.0" 11 | ) 12 | 13 | func (d *OpencontrolData) populateCacheDir(revision string) error { 14 | repo := make([]common.RemoteSource, 1) 15 | repo[0] = schema.VCSEntry{ 16 | URL: "https://github.com/ComplianceAsCode/redhat", 17 | Revision: revision, 18 | Path: ""} 19 | getter := resources.NewVCSAndLocalGetter(opencontrol.YAMLParser{}) 20 | return getter.GetRemoteResources(d.cacheDir, "opencontrols", repo) 21 | } 22 | 23 | func NewOpencontrolData(revision, cacheDir string) (*OpencontrolData, error) { 24 | res := OpencontrolData{cacheDir: cacheDir} 25 | err := res.populateCacheDir(revision) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | var errs []error 31 | res.workspace, errs = lib.LoadData(res.cacheDir, res.certDir()+"dhs-4300a.yaml") 32 | if errs != nil { 33 | msg := "Error occurred during loading open control masonry data" 34 | for _, e := range errs { 35 | msg = fmt.Sprintf("%s: %v", msg, e) 36 | } 37 | return nil, errors.New(msg) 38 | } 39 | return &res, res.buildCache() 40 | } 41 | -------------------------------------------------------------------------------- /pkg/masonry/certifications.go: -------------------------------------------------------------------------------- 1 | package masonry 2 | 3 | import ( 4 | "fmt" 5 | "github.com/opencontrol/compliance-masonry/pkg/lib/certifications" 6 | "github.com/opencontrol/compliance-masonry/pkg/lib/common" 7 | "io/ioutil" 8 | ) 9 | 10 | type StandardSubset map[string]bool 11 | 12 | type Certification struct { 13 | Key string 14 | Controls map[string]StandardSubset 15 | } 16 | 17 | func (d *OpencontrolData) GetAllCertifications() map[string]Certification { 18 | return d.certificationsCache 19 | } 20 | 21 | func (d *OpencontrolData) buildCache() error { 22 | d.certificationsCache = map[string]Certification{} 23 | fileinfos, err := ioutil.ReadDir(d.certDir()) 24 | if err != nil { 25 | return err 26 | } 27 | for _, fileinfo := range fileinfos { 28 | cert, err := certifications.Load(d.certDir() + fileinfo.Name()) 29 | if err != nil { 30 | return err 31 | } 32 | controls := map[string]StandardSubset{} 33 | for _, name := range cert.GetSortedStandards() { 34 | controls[name], err = d.filterKeysInStandard(cert, name) 35 | if err != nil { 36 | return err 37 | } 38 | } 39 | 40 | d.certificationsCache[cert.GetKey()] = Certification{ 41 | Key: cert.GetKey(), 42 | Controls: controls, 43 | } 44 | } 45 | return nil 46 | } 47 | 48 | func (d *OpencontrolData) filterKeysInStandard(cert common.Certification, standardName string) (StandardSubset, error) { 49 | standard, found := d.workspace.GetStandard(standardName) 50 | if !found { 51 | return nil, fmt.Errorf("Did not found standard %s referenced by certification %s", standardName, cert.GetKey()) 52 | } 53 | validControls := standard.GetControls() 54 | res := StandardSubset{} 55 | for _, ctrl := range cert.GetControlKeysFor(standardName) { 56 | _, found = validControls[ctrl] 57 | if found { 58 | res[ctrl] = true 59 | } 60 | } 61 | return res, nil 62 | } 63 | 64 | func (d *OpencontrolData) certDir() string { 65 | return d.cacheDir + "/certifications/" 66 | } 67 | -------------------------------------------------------------------------------- /pkg/masonry/logical_view.go: -------------------------------------------------------------------------------- 1 | package masonry 2 | 3 | import ( 4 | "fmt" 5 | "github.com/opencontrol/compliance-masonry/pkg/lib/common" 6 | ) 7 | 8 | // CustomControl is object that ties together information from standard with product specific "satisfaction" description 9 | type CustomControl struct { 10 | Key string 11 | Control common.Control 12 | Satisfies common.Satisfies 13 | } 14 | 15 | func standardToLogicalView(s common.Standard) map[string][]CustomControl { 16 | result := make(map[string][]CustomControl) 17 | controls := s.GetControls() 18 | for _, controlName := range s.GetSortedControls() { 19 | control := controls[controlName] 20 | _, ok := result[control.GetFamily()] 21 | if !ok { 22 | result[control.GetFamily()] = make([]CustomControl, 0) 23 | } 24 | result[control.GetFamily()] = append(result[control.GetFamily()], CustomControl{ 25 | Key: controlName, 26 | Control: control}) 27 | } 28 | return result 29 | } 30 | 31 | var validImplementationStatuses = []string{"complete", "partial", "not applicable", "planned", "unsatisfied", "unknown", "none"} 32 | 33 | type ControlsByFamilies map[string]map[string][]CustomControl 34 | 35 | func (ms *OpencontrolData) ComponentLogicalView(c common.Component) map[string]interface{} { 36 | ctrls, problems := ms.controlsByFamilies(c) 37 | result := make(map[string]interface{}) 38 | result["name"] = c.GetName() 39 | result["controls"] = ctrls 40 | result["errors"] = problems 41 | return result 42 | } 43 | 44 | func (ms *OpencontrolData) controlsByFamilies(c common.Component) (ControlsByFamilies, []string) { 45 | result := make(ControlsByFamilies) 46 | problems := make([]string, 0) 47 | 48 | for _, satisfy := range c.GetAllSatisfies() { 49 | standardKey := satisfy.GetStandardKey() 50 | _, ok := result[standardKey] 51 | if !ok { 52 | standard, found := ms.GetStandard(standardKey) 53 | if found { 54 | result[standardKey] = standardToLogicalView(standard) 55 | } 56 | 57 | } 58 | found := false 59 | for groupId, group := range result[standardKey] { 60 | for i, cc := range group { 61 | if cc.Key == satisfy.GetControlKey() { 62 | if cc.Satisfies != nil { 63 | problems = append(problems, fmt.Sprintf("Found duplicate item: %s", cc.Key)) 64 | } 65 | 66 | result[standardKey][groupId][i].Satisfies = satisfy 67 | found = true 68 | 69 | switch satisfy.GetImplementationStatus() { 70 | case "complete", "partial", "not applicable", "planned", "unsatisfied", "unknown", "none": 71 | break 72 | default: 73 | problems = append(problems, 74 | fmt.Sprintf("Found non-standard implementation_status: %s. Expected one of %s.", 75 | satisfy.GetImplementationStatus(), validImplementationStatuses)) 76 | break 77 | } 78 | 79 | break 80 | } 81 | 82 | } 83 | if found { 84 | break 85 | } 86 | } 87 | if !found { 88 | problems = append(problems, fmt.Sprintf("Could not find reference %s in the standard %s", satisfy.GetControlKey(), standardKey)) 89 | 90 | } 91 | } 92 | 93 | return result, problems 94 | } 95 | -------------------------------------------------------------------------------- /pkg/masonry/singleton.go: -------------------------------------------------------------------------------- 1 | package masonry 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | var instance *OpencontrolData 8 | var mux sync.Mutex 9 | 10 | // GetInstance gets memory representation of the masonry cache 11 | func GetInstance() *OpencontrolData { 12 | if instance == nil { 13 | mux.Lock() 14 | mux.Unlock() 15 | if instance == nil { 16 | Refresh() 17 | } 18 | } 19 | return instance 20 | } 21 | 22 | // Refresh function refreshes masonry data 23 | func Refresh() error { 24 | mux.Lock() 25 | defer mux.Unlock() 26 | data, err := NewOpencontrolData("master", "/var/tmp/ocdb/masonry_cache") 27 | if err != nil { 28 | return err 29 | } 30 | instance = data 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /pkg/masonry/stats/history.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import ( 4 | "github.com/RedHatGov/ocdb/pkg/git" 5 | "github.com/RedHatGov/ocdb/pkg/masonry" 6 | "github.com/opencontrol/compliance-masonry/pkg/lib/common" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | const ( 12 | // how many months back we want to in the statistics? 13 | startingYear = 2020 14 | startingMonth = 01 15 | ocGit = "https://github.com/ComplianceAsCode/redhat" 16 | ocDir = "/var/tmp/ocdb/ComplianceAsCode.redhat" 17 | ) 18 | 19 | type HistoricalStats map[string]ComponentStats 20 | 21 | type ComponentStats map[string]CertificationStats 22 | 23 | type CertificationStats struct { 24 | Certification string 25 | History []ResultSnapshot 26 | PerFamily map[string]ControlResponses 27 | } 28 | 29 | type ResultSnapshot struct { 30 | Time time.Time 31 | Stats ControlResponses 32 | } 33 | 34 | type ControlResponses map[string]int 35 | 36 | var hsInstance *HistoricalStats 37 | var hsMux sync.Mutex 38 | 39 | func getHistoricalStats() *HistoricalStats { 40 | if hsInstance == nil { 41 | RefreshHistoryStatistics() 42 | } 43 | return hsInstance 44 | } 45 | 46 | func GetHistoricalStats(componentID string) (ComponentStats, bool) { 47 | instance := getHistoricalStats() 48 | stats, found := (*instance)[componentID] 49 | return stats, found 50 | } 51 | 52 | func RefreshHistoryStatistics() error { 53 | hsMux.Lock() 54 | defer hsMux.Unlock() 55 | 56 | startDate := time.Date(startingYear, time.Month(startingMonth), 1, 0, 0, 0, 0, time.UTC) 57 | res, err := buildHistoricalStats(startDate) 58 | if err != nil { 59 | return err 60 | } 61 | hsInstance = &res 62 | return nil 63 | } 64 | 65 | func buildHistoricalStats(startDate time.Time) (HistoricalStats, error) { 66 | res := HistoricalStats{} 67 | gitStartDate := startDate.AddDate(0, -1, 0) 68 | err := git.PullOrClone(ocDir, ocGit, &(gitStartDate)) 69 | if err != nil { 70 | return res, err 71 | } 72 | 73 | for date := range generateDatesBiMonthly(startDate) { 74 | oc, err := opencontrolsByDate(ocDir, date) 75 | if err != nil { 76 | return res, err 77 | } 78 | 79 | for _, component := range oc.GetAllComponents() { 80 | res.AddData(date, oc.GetAllCertifications(), component) 81 | } 82 | } 83 | return res, nil 84 | } 85 | 86 | func (stats HistoricalStats) AddData(date time.Time, certifications map[string]masonry.Certification, component common.Component) { 87 | _, found := stats[component.GetKey()] 88 | if !found { 89 | stats[component.GetKey()] = ComponentStats{} 90 | } 91 | stats[component.GetKey()].AddData(date, certifications, component) 92 | } 93 | 94 | func (stats ComponentStats) AddData(date time.Time, certifications map[string]masonry.Certification, component common.Component) { 95 | satisfiesMap := map[string]string{} 96 | for _, sat := range component.GetAllSatisfies() { 97 | satisfiesMap[sat.GetControlKey()] = sat.GetImplementationStatus() 98 | } 99 | 100 | for _, cert := range certifications { 101 | _, found := stats[cert.Key] 102 | if !found { 103 | stats[cert.Key] = CertificationStats{Certification: cert.Key, History: []ResultSnapshot{}} 104 | } 105 | cs := stats[cert.Key] 106 | cs.History = append(cs.History, resultSnapshot(date, cert, satisfiesMap)) 107 | cs.buildPerFamilyStats(cert, satisfiesMap) 108 | stats[cert.Key] = cs 109 | } 110 | } 111 | 112 | func (stats *CertificationStats) buildPerFamilyStats(cert masonry.Certification, satisfiesMap map[string]string) { 113 | stats.PerFamily = map[string]ControlResponses{} 114 | for standardName, subSet := range cert.Controls { 115 | if standardName == "NIST-800-53" { 116 | for ctrlID := range subSet { 117 | family := ctrlID[0:2] 118 | _, found := stats.PerFamily[family] 119 | if !found { 120 | stats.PerFamily[family] = ControlResponses{} 121 | } 122 | 123 | stats.PerFamily[family].AddData(ctrlID, satisfiesMap) 124 | } 125 | } 126 | } 127 | } 128 | 129 | func resultSnapshot(date time.Time, cert masonry.Certification, satisfiesMap map[string]string) ResultSnapshot { 130 | res := ResultSnapshot{Time: date, Stats: ControlResponses{}} 131 | for standardName, subSet := range cert.Controls { 132 | if standardName == "NIST-800-53" { 133 | for ctrlID := range subSet { 134 | res.Stats.AddData(ctrlID, satisfiesMap) 135 | } 136 | } 137 | } 138 | return res 139 | } 140 | 141 | func (responses ControlResponses) AddData(ctrlID string, satisfiesMap map[string]string) { 142 | status, found := satisfiesMap[ctrlID] 143 | if !found { 144 | status = "unknown" 145 | } 146 | prev, found := responses[status] 147 | if !found { 148 | prev = 0 149 | } 150 | responses[status] = prev + 1 151 | } 152 | 153 | func opencontrolsByDate(ocDir string, date time.Time) (*masonry.OpencontrolData, error) { 154 | gitSha, err := git.LastCommitBy(ocDir, date) 155 | if err != nil { 156 | return nil, err 157 | } 158 | return masonry.NewOpencontrolData(gitSha, "/var/tmp/ocdb/ComplianceAsCode.redhat.rev") 159 | } 160 | 161 | func generateDatesBiMonthly(since time.Time) chan time.Time { 162 | today := time.Now() 163 | ch := make(chan time.Time) 164 | go func() { 165 | for date := since; today.After(date); date = date.AddDate(0, 2, 0) { 166 | ch <- date 167 | } 168 | ch <- today 169 | close(ch) 170 | }() 171 | return ch 172 | } 173 | -------------------------------------------------------------------------------- /pkg/masonry/wrapper.go: -------------------------------------------------------------------------------- 1 | package masonry 2 | 3 | import ( 4 | "github.com/opencontrol/compliance-masonry/pkg/lib/common" 5 | ) 6 | 7 | type OpencontrolData struct { 8 | workspace common.Workspace 9 | cacheDir string 10 | certificationsCache map[string]Certification 11 | } 12 | 13 | func (d *OpencontrolData) GetAllComponents() []common.Component { 14 | return d.workspace.GetAllComponents() 15 | } 16 | 17 | func (d *OpencontrolData) GetComponent(id string) (common.Component, bool) { 18 | return d.workspace.GetComponent(id) 19 | } 20 | 21 | func (d *OpencontrolData) GetAllStandards() []common.Standard { 22 | return d.workspace.GetAllStandards() 23 | } 24 | 25 | func (d *OpencontrolData) GetStandard(id string) (common.Standard, bool) { 26 | return d.workspace.GetStandard(id) 27 | } 28 | 29 | func (d *OpencontrolData) PathToComponentYaml(componentId string) string { 30 | return d.cacheDir + "/components/" + componentId + "/component.yaml" 31 | } 32 | -------------------------------------------------------------------------------- /pkg/static/assets.go: -------------------------------------------------------------------------------- 1 | package static 2 | 3 | import "github.com/gobuffalo/packr/v2" 4 | 5 | // Represents files under our the assets directory 6 | var AssetsBox = packr.New("app:assets", "../../public") 7 | -------------------------------------------------------------------------------- /pkg/utils/log_writer.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "github.com/gobuffalo/buffalo" 4 | 5 | var Log buffalo.Logger 6 | 7 | func SetLogger(logger buffalo.Logger) { 8 | Log = logger 9 | } 10 | 11 | type LogWriter struct{} 12 | 13 | func (LogWriter) Write(p []byte) (n int, err error) { 14 | length := len(p) 15 | if p[length-1] == '\n' { 16 | p = p[:length-1] 17 | } 18 | Log.Debug(string(p)) 19 | return length, nil 20 | } 21 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /public/srg-to-csv.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | https://public.cyber.mil/stigs/downloads/?_dl_facet_stigs=operating-systems%2Cgeneral-purpose-os 13 | 14 | 15 | 16 | 17 | CCI 18 | SRGID 19 | STIGID 20 | SRG Requirement 21 | Requirement 22 | SRG VulDiscussion 23 | VulDiscussion 24 | Status 25 | SRG Check 26 | Check 27 | SRG Fix 28 | Fix 29 | Severity 30 | Mitigation 31 | Artifact Description 32 | Status Justification 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | : 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | Applicable - Inherently Meets 109 | 110 | 111 | N/A 112 | 113 | 114 | Applicable - Configurable 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /templates/_flash.plush.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= for (k, messages) in flash { %> 4 | <%= for (msg) in messages { %> 5 | 11 | <% } %> 12 | <% } %> 13 |
14 |
15 | -------------------------------------------------------------------------------- /templates/application.plush.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | OpenControl Database 9 | 10 | 11 | "> 12 | "> 13 | 14 | 15 | 22 | <%= javascriptTag("app.js") %> 23 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /templates/index.plush.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedHatGov/ocdb/23d941ac48d1f789d309def511a1910d07fdf2ee/templates/index.plush.html -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "rootDir": ".", 5 | "outDir": "dist", 6 | "module": "esnext", 7 | "target": "es5", 8 | "lib": ["es6", "dom"], 9 | "sourceMap": true, 10 | "jsx": "react", 11 | "moduleResolution": "node", 12 | "forceConsistentCasingInFileNames": true, 13 | "noImplicitReturns": true, 14 | "noImplicitThis": true, 15 | "noImplicitAny": false, 16 | "allowJs": true, 17 | "esModuleInterop": true, 18 | "allowSyntheticDefaultImports": true, 19 | "strict": true, 20 | "resolveJsonModule": true, 21 | "paths": { 22 | "@app/*": ["assets/src/app/*"], 23 | "@assets/*": ["node_modules/@patternfly/react-core/dist/styles/assets/*"] 24 | }, 25 | }, 26 | "include": [ 27 | "**/*.ts", 28 | "**/*.tsx" 29 | ], 30 | "exclude": ["node_modules"] 31 | } 32 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const Webpack = require("webpack"); 2 | const Glob = require("glob"); 3 | const path = require('path'); 4 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 6 | const ManifestPlugin = require("webpack-manifest-plugin"); 7 | const CleanObsoleteChunks = require('webpack-clean-obsolete-chunks'); 8 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); 9 | const LiveReloadPlugin = require('webpack-livereload-plugin'); 10 | const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); 11 | 12 | const configurator = { 13 | plugins() { 14 | var plugins = [ 15 | new CleanObsoleteChunks(), 16 | new Webpack.ProvidePlugin({$: "jquery",jQuery: "jquery"}), 17 | new MiniCssExtractPlugin({filename: "[name].[contenthash].css"}), 18 | new CopyWebpackPlugin({patterns: [{from: "./assets",to: ""}]}, {copyUnmodified: true,ignore: ["css/**", "js/**", "src/**"] }), 19 | new Webpack.LoaderOptionsPlugin({minimize: true,debug: false}), 20 | new ManifestPlugin({fileName: "manifest.json"}) 21 | ]; 22 | 23 | return plugins 24 | }, 25 | 26 | moduleOptions: function() { 27 | return { 28 | rules: [ 29 | { 30 | test: /\.s[ac]ss$/, 31 | use: [ 32 | MiniCssExtractPlugin.loader, 33 | { loader: "css-loader", options: {sourceMap: true}}, 34 | { loader: "sass-loader", options: {sourceMap: true, includePaths: [ "/node_modules/@patternfly/patternfly/" ]}} 35 | ] 36 | }, 37 | { test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/}, 38 | { test: /\.jsx?$/, loader: "babel-loader",exclude: /node_modules/ }, 39 | { test: /\.(woff|woff2|ttf|svg|png|jpg)(\?v=\d+\.\d+\.\d+)?$/,use: "url-loader"}, 40 | { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,use: "file-loader" }, 41 | { test: require.resolve("jquery"),use: "expose-loader?jQuery!expose-loader?$"}, 42 | { test: /\.css$/, use: ["style-loader", "css-loader"] }, 43 | { test: /\.mdx?$/, use: ['babel-loader', '@mdx-js/loader']}, 44 | ] 45 | } 46 | }, 47 | 48 | buildConfig: function(){ 49 | // NOTE: If you are having issues with this not being set "properly", make 50 | // sure your GO_ENV is set properly as `buffalo build` overrides NODE_ENV 51 | // with whatever GO_ENV is set to or "development". 52 | const env = process.env.NODE_ENV || "development"; 53 | 54 | var config = { 55 | mode: env, 56 | entry: { app: path.resolve(__dirname, 'assets', 'src', 'index.tsx') }, 57 | output: {filename: "[name].[hash].js", path: `${__dirname}/public/assets`}, 58 | plugins: configurator.plugins(), 59 | module: configurator.moduleOptions(), 60 | resolve: { 61 | extensions: ['.ts', '.js', '.json', '.tsx', '.md'], 62 | plugins: [ 63 | new TsconfigPathsPlugin({ 64 | configFile: path.resolve(__dirname, './tsconfig.json') 65 | }) 66 | ] 67 | }, 68 | node: { fs: 'empty' }, 69 | } 70 | 71 | if( env === "development" ){ 72 | config.plugins.push(new LiveReloadPlugin({appendScriptTag: true})) 73 | return config 74 | } 75 | 76 | const uglifier = new UglifyJsPlugin({ 77 | uglifyOptions: { 78 | beautify: false, 79 | mangle: {keep_fnames: true}, 80 | output: {comments: false}, 81 | compress: {} 82 | } 83 | }) 84 | 85 | config.optimization = { 86 | minimizer: [uglifier] 87 | } 88 | 89 | return config 90 | } 91 | } 92 | 93 | module.exports = configurator.buildConfig() 94 | --------------------------------------------------------------------------------