A CLI tool for building and publishing an organization's full policies, standards, and procedures (PSPs) in support of modern security operations and compliance.
The output format is Markdown. For instructions on converting markdown to other formats like HTML and PDF, see notes below.
First-time users of the tool can choose one of the execution methods below and
run psp build
to be interactively prompted for configuration values. This will
generate a config.json
file that may be used to speed-up future invocations.
JupiterOne users with existing content may begin using the CLI by downloading the PSP zip file in the Policies app.
Run the following command to install the policy builder locally using NPM.
npm install -g @jupiterone/security-policy-builder
If you do not have Node and/or NPM installed locally, you may do so via:
- Install NVM with:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
- Install Node with
nvm install stable
If you are comfortable using Docker, you can also use our Dockerhub pspbuilder image, by issuing the command:
docker pull jupiterone/pspbuilder
This will cache the docker image locally on your machine.
The first time you run the psp build
command, you will be prompted for several
inputs, such as company name, to be included in your policy text. Save this to a
file, say config.json
, when prompted. This will use the default
policy templates
maintained by JupiterOne to render a basic, but fairly complete set of
information security policies and procedures.
cd
into a directory where you would like your PSP files to reside (we
recommend keeping the generated templates
directory--see below--under version
control!) and perform one of the following commands:
If you installed from NPM above, issue:
psp build
If you're using the provided docker image, issue:
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder psp build -o /mnt/docs -p /mnt/partials -s /mnt/templates
Remember to save your config to a file, which you can reference the next time
you'd like to rebuild the policies and procedures with the -c
or --config
option flag. This JSON document stores your organization
template variables
referenced from documents in the templates
folder, and also stores the
information architecture for your documents (how the policies and procedures
fragments should be stitched together). We recommended all policies available in
the default config.json
to be adopted for your security program. The
config.json
file includes the procedures/controls you choose to adopt, which
will be included in the final rendered policy docs by the tool.
The output of a successful first run will be the creation of three directories:
templates
- raw markdown templates that represent the source of truth for your policies and procedures.partials
- partially rendered markdown fragments used to assemble thedocs
. This dir is intermediate output sometimes useful for debugging purposes, and may largely be ignored.docs
- The final Markdown produced by the tool, assembled frompartials
fragments.
You will invariably want to edit these PSPs to reflect the specifics of your organization's information security program. See "PSP Best Practices" below for additional details on versioning and deployment.
IMPORTANT: To edit the policies and procedures, use the template files in
./templates
and re-run the psp build
command. Do not edit the ./docs
and
./partials
files directly as they will be overwritten on the next build.
Once you've edited your template files, you're ready to build again with:
psp build -t ./templates -c ./config.json
or
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder psp build -t /mnt/templates -o /mnt/docs -p /mnt/partials
The policybuilder tools supports publishing to JupiterOne and Confluence, via
the publish
subcommand.
If you have an account on the JupiterOne security platform, you can run the following command to publish the contents of your policies and procedures to your JupiterOne account, so that you and others in your organization can access them online.
psp publish -c ./templates/config.json -t ./templates -a $J1_ACCOUNT_ID -k $J1_API_TOKEN
or
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder psp publish -c /mnt/config.json -t /mnt/templates -a $J1_ACCOUNT_ID -k $J1_API_TOKEN
Your JupiterOne token must have Policies:Admin
privilege, or be issued by an
account Administrator, in order to publish the contents.
You can also publish the policies to a Confluence wiki space. Simply run the
psp publish
command with the --confluence
option.
psp publish --confluence
You will be prompted to enter your Confluence domain and space key, and username/password:
? Confluence domain (the vanity subdomain before '.atlassian.net'):
? Confluence space key:
? Confluence username:
? Confluence password: [hidden]
Published 35 docs to Confluence.
Or, provide necessary configuration options for non-interactive publishing:
psp publish --confluence --site <subdomain> --space <KEY> --docs <path> -u <username/email> -k <key/password>
The program will save the page ID for each published policy document locally to
a file in the current directory: confluence-pages.json
. Make sure this file is
retained because the program will use the page ID for each policy to update
the Confluence page the next time it is run.
We recommend creating a dedicated wiki space for these security policies.
The PSPs supported by the tool are meant to be automatically generated from source. We recommend the following practices:
We highly recommend you practice policy-as-code and version your templates
dir
and config.json
file. If you use git
for version control, we recommend
putting the following in your project's .gitignore
:
docs
partials
Doing this makes it obvious what is to be edited in order to update your PSPs, and prevents confusion.
If your versioning system supports it, we recommend limiting merge authority to authorized security staff only.
Building and publishing the PSPs upon authorized merge to main branch is
supported via the -n
or --noninteractive
flags. Do something like:
#!/bin/bash
set -euo pipefail
cd to/cloned/repo
# build documentation
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder psp build -c /mnt/config.json -o /mnt/docs -t /mnt/templates --noninteractive
# publish templates to JupiterOne graph
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder psp publish -c /mnt/config.json -t /mnt/templates -a $J1_ACCOUNT_ID -k $J1_API_TOKEN --noninteractive
# generate static HTML in 'site' directory
# mkdocs command expects the YAML file to be at the root of the project
cp docs/mkdocs.yml .
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder mkdocs build -f /mnt/mkdocs.yml
# copy to static site host (here, AWS S3 bucket)
cd site
aws s3 cp --recursive . s3://mybucket/location
We recommend the mkdocs
tool for this. See above example in "CI/CD" which does
mkdocs build
.
You may edit your config.json
file directly to provide input to the
configurable questions. The config.json
file contains the following sections:
organization
- You can edit this section directly to provide answers to the questions that
are promptly by the
psp-builder
CLI. - You can also add your own custom variables in this section -- e.g.
"variableName": "value"
. You will need to make sure to add the same variable(s) to your templates in the format of{{variableName}}
. - Note that if the variable is a URL/URI, you will need to add the
&
symbol to your variables in the templates -- e.g.{{&variableURL}}
.
standards
- Contains references to various compliance standards and frameworks.
- DO NOT edit this section.
policies
- Contains all available policies and the corresponding procedures that implements and enforces each policy.
- It is recommended that all policies to be included in your security program and documentation, therefore, you should NOT edit this section.
procedures
-
Contains the individual procedure documentations.
-
Each procedure includes the following
- A
summary
to provide high level guidance about that particular procedure and its implementation. This is for your reference. - A set of
resources
that will help with implementation and/or selecting a third party vendor solution. - A
provider
property, pre-populated with the recommended solution, if applicable. You may update this to the solution you have actually selected. The policy builder will update the documentation text within that procedure accordingly. - If you choose to exclude a procedure from your final policy documentation,
you may set the
adopted
flag tofalse
. The policy builder with skip those when compiling the policies.
- A
If you'd prefer not to use the image provided by DockerHub, you may build your own docker image by cloning this repository, and running:
docker build -t pspbuilder .
The static HTML files generated by mkdocs (see "CI/CD" above for example) may be viewed locally by doing:
cd site
python3 -m http.server 8000
open http://localhost:8000
Note: local mkdocs usage is not supported.
pip install --upgrade pip
pip install mkdocs mkdocs-material
See http://www.mkdocs.org for more info. Additionally, mkdocs is configured to
use the mkdocs-material
theme. Instructions
can be found here.
Pandoc
can be used to automatically convert the markdown files into PDF or
Word documents.
The supported jupiterone/pspbuilder
docker image has the necessary pandoc
dependencies installed. You may issue commands like:
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder-extras pandoc /mnt/docs/filename.md -f markdown -t latex --pdf-engine=xelatex --variable monofont="Monaco" -o /mnt/pdf/filename.pdf
to convert a single markdown file into a PDF.
NOTE: Local pandoc usage is not supported.
To install and configure pandoc
locally on your system, follow the
installation instructions here:
pandoc.org/installing.html
or issue the following commands:
Install Pandoc:
brew install pandoc
Install pandoc-latex-admonition, which is a pandoc filter for adding admonition:
pip install pandoc-latex-admonition
Download and install LaTex, or MacTeX. The smaller distribution, BasicTeX is sufficient, but additional packages are required:
sudo tlmgr install collection-fontsrecommended
sudo tlmgr install mdframed
sudo tlmgr install needspace
sudo tlmgr install ucharcat
sudo tlmgr install tcolorbox
sudo tlmgr install environ
sudo tlmgr install trimspaces
NOTE: on macOS systems, you will likely also need to install XeLaTeX from here: http://www.texts.io/support/0001/
Start a new terminal session to ensure pandoc
runs. Note that some UTF-8
characters
may not be supported out-of-the-box.
The --pdf-engine=xelatex --variable monofont="Monaco"
options help, but other
fonts may be required if your content needs them.
Example script for generating individual PDF policy documents:
#!/bin/bash
cd ./docs
mkdir pdf
for filename in *.md; do
echo $filename
pandoc $filename -f markdown -t latex --pdf-engine=xelatex --variable monofont="Monaco" -o ./pdf/$filename.pdf
done
Example script for generating a combined PDF policy document, using Docker:
Create a small bash script, called pdf.sh
:
#!/bin/bash
cd /mnt
mkdir pdf
cd /mnt/docs
pandoc *.md -f markdown -t latex --latex-engine=xelatex --variable monofont="inconsolata" --toc -o /mnt/pdf/infosec-policies.pdf
Then, issue:
docker run -it -v "$PWD":/mnt --rm jupiterone/pspbuilder-extras /mnt/pdf.sh
This should stitch together all of your markdown files (in alphabetical order
returned by the bash glob, *
). You could replace this with individual ordering
of file arguments if you wanted more control of the sequencing.
Example script for generating Word documents:
mkdir docx
pandoc model.md *.md -f markdown -t docx --toc -o ./docx/infosec-policies.docx
The current version of the policy builder supports generating a lightweight HIPAA self assessment report, based on a few key questions and the adoption of policies and procedures.
./bin/psp assess --standard hipaa --config <location_of_your_json_config_file> [options]
The above command generates a HIPAA self assessment report in the
./assessments
directory. The report contains mapping of your adopted
policies/procedures to each specific HIPAA regulation requirement. It also
contains placeholders, where applicable, for you to provide additional details.
Gaps identified will be called out in the command line output as well as in the
report itself.