Community
Questions Library
Docs
Blog
Events
Swag
Github
Slack
JupiterOne
Discussions
Release Notes
Contact Us
Compliance API Endpoints - AskJ1 Community
<main> <article class="userContent"> <p>This article contains a list of compliance actions from the JupiterOne UI that a user can perform using the GraphQL API endpoint.</p> <p>See the <a rel="nofollow" href="https://jupiterone.vanillacommunities.com/kb/articles/794-jupiterone-api">JupiterOne Platform API</a> for an introduction to the JupiterOne API.</p> <h3 data-id="some-key-things-to-note">Some key things to note:</h3> <ul><li>Most of the compliance-related data is exposed in one large GraphQL graph. The sections in this document break down the API by object, but you can access them at the same GraphQL resolver.</li> <li>To see the full GraphQL graph, perform <a rel="nofollow" href="https://graphql.org/learn/introspection/">introspection</a> on the public API.</li> </ul><p><strong>Base URL</strong>: <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">https://api.us.jupiterone.io</code></p> <p><strong>Method</strong>: <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">POST</code></p> <p><strong>Endpoint for compliance operations</strong>: <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">/graphql</code></p> <p><strong>Rate Limits</strong>: Rate limiting is enforced based on your account tier. A <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">429</code> HTTP response code indicates the limit has been reached. The API does not currently return any rate limit headers.</p> <h2 data-id="list-frameworks">List Frameworks</h2> <p>This query retrieves a list of all frameworks (benchmarks, compliance standards, questionnaires) that were added to your JupiterOne account, as well as any metadata about them. Note, this query does not retrieve the entire framework model, only the base properties of a framework.</p> <p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">query ListFrameworks { complianceFrameworks { benchmarks { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters { keys values } lastEvaluationTimestamp } standards { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters { keys values } lastEvaluationTimestamp } questionnaires { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters { keys values } lastEvaluationTimestamp } } } </pre> <h2 data-id="get-framework">Get Framework</h2> <p>Retrieves the full ComplianceFramework model by ID. It includes details such as overall summary, nested groups and framework items, linked controls, and more.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code>: ComplianceFrameworkInput <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">id</code> - The unique identifier for this resource<br><strong>Query</strong></li> </ul></li> </ul><pre class="code codeBlock" spellcheck="false" tabindex="0">query ComplianceFramework($input: ComplianceFrameworkInput!) { complianceFramework(input: $input) { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters lastEvaluationTimestamp isApplicableForThisUser summaryConfig { showPoliciesAndProcedures showEvidence showGapAnalysis showAuditTracking } summary { id totalFrameworkItems applicableFrameworkItems compliantPercentageSummary { id overallCompliantPercentage compliantPercentageExcludingPoliciesAndProcedures } evidenceCollectionSummary { id hasEvidence hasInternalEvidenceCollected hasExternalEvidenceAttached hasQuestionnaireAnswer } gapAnalysisSummary { id fulfilled gapDetected warning unknown } policyItemLinkSummary { id hasLinkedPolicyItem } } groups { id frameworkItems { id evidence { questionEvaluations { id } notes { id } questionnaireAnswer { id } links { id } externalUploadEvidences { id externalUploadId externalUpload { id } } } libraryItems { inheritedEvidenceLibraryItems { id policyItemId linkedPolicyItem { id linkedPolicy { id } } evidence { questionEvaluations { id } notes { id } questionnaireAnswer { id } links { id } externalUploadEvidences { id externalUploadId externalUpload { id } } } } ignoredEvidenceLibraryItems { id policyItemId linkedPolicyItem { id linkedPolicy { id } } } } } } } } </pre> <h2 data-id="create-framework-from-template">Create Framework from Template</h2> <p>This query creates an empty framework (no groups or framework items). See the <br><a rel="nofollow" href="https://github.com/JupiterOne/security-policy-templates/tree/master/templates/standards">security-policy-templates project</a> for templated JSON frameworks.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">name</code>: The human readable name of this compliance framework - Example: HIPPA</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">version</code>: The version of this compliance framework - Example: 2013 or v.1.2</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">frameworkType</code>: <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">BENCHMARK</code>, <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">QUESTIONNAIRE</code>, or <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">STANDARD</code></li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">webLink</code>: An external web link to the framework's definition</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">scopeFilters</code>: <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">key</code>: Key to filter the graph results by</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">values</code>: Array of values to include in the graph results</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">mutation CreateFramework($input: CreateComplianceFrameworkInput!) { createComplianceFramework(input: $input) { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters { keys values } lastEvaluationTimestamp } } </pre> <h2 data-id="import-framework-from-template">Import Framework from Template</h2> <p>This query imports a framework from the J1 predefined templates. See the <br><a rel="nofollow" href="https://github.com/JupiterOne/security-policy-templates/tree/master/templates/standards">security-policy-templates project</a> for templated JSON frameworks.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">complianceFrameworkName</code>: The name of the framework to import <ul><li>These names can be found either in the <a rel="nofollow" href="https://github.com/JupiterOne/security-policy-templates/tree/master/templates/standards">security-policy-templates project</a> or as an output of the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">ImportableComplianceFrameworkTemplates</code> query.</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">mutation ImportFrameworkByName($input: ImportComplianceFrameworkByNameInput!) { importComplianceFrameworkByName(input: $input) { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters { keys values } lastEvaluationTimestamp } } </pre> <h2 data-id="import-framework-from-json">Import Framework from JSON</h2> <p>This query imports a framework using raw JSON. The JSON must adhere to the structure defined in the <br><a rel="nofollow" href="https://github.com/JupiterOne/security-policy-templates/tree/master/templates/standards">security-policy-templates project</a>.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">complianceFrameworkJsonString</code>: The JSON string to import</li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">mutation ImportFramework($input: ImportComplianceFrameworkInput!) { importComplianceFramework(input: $input) { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters { keys values } lastEvaluationTimestamp } } </pre> <h2 data-id="update-review-configurations">Update Review Configurations</h2> <p>The following queries update the review configuration of a framework, group, or frameworkItem. Each query requires the ID of the framework you are updating as well as an input variable object, which includes a list of owner emails, the review frequency, and the origin of action links (the domain of your JupiterOne account).</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">frameworkId</code>: The unique identifier for the framework, returned by the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">List frameworks</code> query.</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code>: The input variable captures additional values, including: the origin of the action link, the owner(s) of the review configuration, and the review frequency. For example:</li> </ul><pre class="code codeBlock" spellcheck="false" tabindex="0">"input": { "actionLink": "<a href="https://apps.us.jupiterone.io/compliance/{frameworkId}/{frameworkItemId?}" rel="nofollow">https://apps.us.jupiterone.io/compliance/{frameworkId}/{frameworkItemId?}</a>", "owners": [ "example@jupiterone.com" ], "reviewFrequency": "SIXTY_DAYS" } </pre> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">actionLink</code>: A link to the item you are configuring this review for</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">owners</code>: A list of email accounts that have an associated user in JupiterOne.</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">reviewFrequency</code>: The frequency that owners will be prompted to review the framework. Valid options include: <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">WEEKLY</code>, <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">MONTHLY</code>, <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">SIXTY_DAYS</code>, <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">ONE_HUNDRED_EIGHTY_DAYS</code>, <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">ANNUALLY</code></li> </ul><h3 data-id="set-update-review-configurations-framework">Set/Update Review Configurations - Framework</h3> <pre class="code codeBlock" spellcheck="false" tabindex="0">mutation SetReviewConfigurationsForComplianceFramework($frameworkId: ID!, $input: SetComplianceReviewConfigurationInput!) { setReviewConfigurationsForComplianceFramework(frameworkId: $frameworkId, input: $input) } </pre> <h3 data-id="set-update-review-configurations-group">Set/Update Review Configurations - Group</h3> <p><strong>Additional Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">groupId</code>: The unique identifier for the group to set this configuration for</li> </ul><p><strong>Mutation</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">mutation SetReviewConfigurationsForComplianceGroup($groupId: ID!, $input: ConfigureRecurringComplianceReviewInput!) { setReviewConfigurationsForComplianceGroup(groupId: $groupId, input: $input) } </pre> <h3 data-id="set-update-review-configurations-frameworkitem">Set/Update Review Configurations - FrameworkItem</h3> <p><strong>Additional Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">frameworkItemId</code>: The unique identifier for the framework item to set this configuration for</li> </ul><p><strong>Mutation</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">mutation SetReviewConfigurationForComplianceFrameworkItem($frameworkItemId: ID!, $input: ConfigureRecurringComplianceReviewInput!) { setReviewConfigurationForComplianceFrameworkItem(frameworkItemId: $frameworkItemId, input: $input) } </pre> <h2 data-id="list-controls-library-items">List Controls (Library Items)</h2> <p>Controls (called "Library Items" in our internal data model) are reusable objects of compliance data that exist outside the context of a framework. You can link the controls to different frameworkItems to provide additional evidence.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">filter</code> - <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">ACCOUNT</code> | <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">FRAMEWORK_ITEM</code></li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">frameworkItemId</code> - When filtering by FRAMEWORK_ITEM, this is the uuid identifier to filter by</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">returnAllPages</code> - Returns all pages of data and ignores any pagination options</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">cursor</code> - Cursor for pagination</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">limit</code> - Pagination page size limit, defaults to 50</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">query ComplianceLibraryItemMetadatas($input: ComplianceLibraryItemMetadatasInput!) { complianceLibraryItemMetadatas(input: $input) { items { id name description ref displayCategory policyItemId webLink linkedPolicyItem { id ref name isAdopted linkedPolicy { id ref name } } } pageInfo { endCursor hasNextPage } } } </pre> <h2 data-id="get-control-with-evidence-and-associated-framework-items">Get Control with Evidence and associated Framework Items</h2> <p>This query exposes more data on top of the base <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">ComplianceLibraryItemMetadatas</code> object. Any information you need about a control is exposed via this query.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">id</code> - Unique identifier of the library item to fetch</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">query ComplianceControl($input: ComplianceLibraryItemInput!) { complianceLibraryItem(input: $input) { id name description ref displayCategory policyItemId webLink linkedPolicyItem { id ref name isAdopted linkedPolicy { id ref name } } frameworkItemMetadatas { id frameworkId name description displayCategory auditStatus webLink evaluationProgress lastEvaluationTimestamp ref frameworkMetadata { id createTimestamp lastUpdatedTimestamp name version frameworkType webLink scopeFilters } } evidence { allEvidence { id evidenceType ... on ComplianceQuestionEvaluation { questionId evaluationResult lastUpdatedTimestamp results { name query rawResultKey recordCount } } ... on ComplianceNote { creatorUserId body createTimestamp name } ... on ComplianceLink { creatorUserId description linkUrl createTimestamp name } ... on ExternalUploadEvidence { lastUpdatedTimestamp creatorUserId body externalUploadId createTimestamp } } questionEvaluations { id questionId lastUpdatedTimestamp evidenceType evaluationResult results { name query rawResultKey recordCount } } notes { id evidenceType creatorUserId body createTimestamp name } links { id evidenceType creatorUserId description linkUrl createTimestamp name } externalUploadEvidences { id evidenceType creatorUserId body externalUploadId createTimestamp lastUpdatedTimestamp } } } } </pre> <h2 data-id="create-control">Create Control</h2> <p>This query creates a control.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">name</code> - The human readable name for this compliance library item - Example: Acceptable Use of End User Computing</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">description</code> - Any other relevant information for this compliance library item</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">ref</code> - Human readable identifier used in question/policy mapping operations - Example: cp-access-aws</li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">webLink</code> - An external web link to this library item's definition</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">query ComplianceControl($input: CreateComplianceLibraryItemInput!) { createComplianceLibraryItem(input: $input) { id name description ref displayCategory policyItemId webLink linkedPolicyItem { id ref name isAdopted linkedPolicy { id ref name } } } </pre> <h2 data-id="get-requirement-framework-item">Get Requirement (Framework Item)</h2> <p>In the API, the term "Framework Item" corresponds to a requirement in the JupiterOne UI</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">id</code> - The ID of the requirement (framework item) to retrieve</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">query complianceFrameworkItem($input: ComplianceFrameworkItemInput!) { complianceFrameworkItem(input: $input) { id name description displayCategory ref evaluationProgress lastEvaluationTimestamp evaluationResult auditStatus groupId webLink summary { id hasLinkedPolicyItem evidenceCollectionSummary { id hasEvidence hasInternalEvidenceCollected hasExternalEvidenceAttached questionnaireAnswer } } } } </pre> <h2 data-id="gap-status">Gap Status</h2> <p>In the Compliance API, the "Gap Status" is exposed via the <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">evaluationResult</code> property on the following objects:</p> <ul><li>Requirement (Framework Item)</li> <li>Control (Library Item)</li> </ul><p>The valid values of <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">evaluationResult</code> are</p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">FULFILLED</code></li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">GAP_DETECTED</code></li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">NOT_APPLICABLE</code></li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">WARNING</code></li> <li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">UNKNOWN</code></li> </ul><h2 data-id="evidence-collection">Evidence Collection</h2> <p>Evidence collection can be performed at the framework, requirement, or control level. In order to complete the process, three<br> actions must be taken in sequential order:</p> <ol><li>Kick off an EvidenceCollectionJob via API</li> <li>Poll for the completion of the EvidenceCollectionJob</li> <li>Use the completed EvidenceCollectionJob to receive an AWS s3 link to download its output</li> </ol><h3 data-id="start-an-evidencecollectionjob-via-api">Start an EvidenceCollectionJob via API</h3> <p>Each object type has a different GraphQL mutation to call to start its EvidenceCollectionJob. Ensure<br> to use the correct mutation for the specified object type.</p> <h4 data-id="start-framework-evidencecollectionjob">Start Framework EvidenceCollectionJob</h4> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">frameworkId</code> - The identifier of the framework to start an EvidenceCollectionJob for</li> </ul></li> </ul><p><strong>Mutation</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0"> mutation startEvidenceCollectionJobforFramework( $input: StartEvidenceCollectionJobForFrameworkInput! ) { startEvidenceCollectionJobforFramework(input: $input) { id accountId userId frameworkId frameworkItemId libraryItemId status progress createTimestamp endTimestamp } } </pre> <h4 data-id="start-requirement-evidencecollectionjob">Start Requirement EvidenceCollectionJob</h4> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">frameworkItemId</code> - The identifier of the requirement(i.e. framework item) to start an EvidenceCollectionJob for</li> </ul></li> </ul><p><strong>Mutation</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0"> mutation startEvidenceCollectionJobforFrameworkItem( $input: StartEvidenceCollectionJobForFrameworkItemInput! ) { startEvidenceCollectionJobforFrameworkItem(input: $input) { id accountId userId frameworkId frameworkItemId libraryItemId status progress createTimestamp endTimestamp } } </pre> <h4 data-id="start-control-evidencecollectionjob">Start Control EvidenceCollectionJob</h4> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">libraryItemId</code> - The identifier of the library item (such as Control) to start an EvidenceCollectionJob for</li> </ul></li> </ul><p><strong>Mutation</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">mutation startEvidenceCollectionJobforLibraryItem( $input: StartEvidenceCollectionJobForLibraryItemInput! ) { startEvidenceCollectionJobforLibraryItem(input: $input) { id accountId userId frameworkId frameworkItemId libraryItemId status progress createTimestamp endTimestamp } } </pre> <h3 data-id="poll-for-the-completion-of-the-evidencecollectionjob">Poll for the completion of the EvidenceCollectionJob</h3> <p>When the job has completed, its <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">status</code> field is set to <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">COMPLETED</code></p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">id</code> - The identifier of the EvidenceCollectionJob to fetch</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">query evidenceCollectionJob($input: EvidenceCollectionJobInput!) { evidenceCollectionJob(input: $input) { id accountId userId frameworkId frameworkItemId libraryItemId status progress createTimestamp endTimestamp } } </pre> <h3 data-id="fetch-aws-s3-download-link-from-the-completed-evidencecollectionjob">Fetch AWS S3 Download Link from the Completed EvidenceCollectionJob</h3> <p>The returned <code class="code codeInline code codeInline" spellcheck="false" tabindex="0">link</code> property is an <a rel="nofollow" href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html">AWS S3 Presigned URL</a> that contains the zipped evidence file to download. This URL will be valid for 2 hours. To generate a new URL (if the timeout<br> is reached), just call the same query below again.</p> <p><strong>Variables</strong></p> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">input</code> <ul><li><code class="code codeInline code codeInline" spellcheck="false" tabindex="0">evidenceCollectionJobId</code> - The identifier of the EvidenceCollectionJob to get the download link for</li> </ul></li> </ul><p><strong>Query</strong></p> <pre class="code codeBlock" spellcheck="false" tabindex="0">query downloadLinkForEvidenceCollectionJob( $input: DownloadLinkForEvidenceCollectionJobInput! ) { downloadLinkForEvidenceCollectionJob(input: $input) { link } } </pre> </article> </main>