# Update policies using API

**URL:** <https://community.sonatype.com/t/update-policies-using-api/7516>\
**Category:** Sonatype Lifecycle & Firewall\
**Tags:** help, nexus-iq, api, policy\
**Created:** [October 21, 2021, 10:21am UTC](https://community.sonatype.com/t/update-policies-using-api/7516 "2021-10-21T10:21:52Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![nikhil.nagesh.chodankar](https://avatars.discourse-cdn.com/v4/letter/n/65b543/32.png) [@nikhil.nagesh.chodankar](https://community.sonatype.com/u/nikhil.nagesh.chodankar)\
**Post date:** [October 21, 2021, 10:21am UTC](https://community.sonatype.com/t/update-policies-using-api/7516/1 "2021-10-21T10:21:52Z")

</div>

I wanted to ask if we can update the policies of Nexus IQ Server using APIs? Our current version is 103.

---

<div class="post-metadata">

**Author:** ![jwhitehouse](https://yyz1.discourse-cdn.com/flex047/user_avatar/community.sonatype.com/jwhitehouse/32/187_2.png) [@jwhitehouse](https://community.sonatype.com/u/jwhitehouse)\
**Post date:** [October 21, 2021, 3:27pm UTC](https://community.sonatype.com/t/update-policies-using-api/7516/2 "2021-10-21T15:27:00Z")

</div>

At this time there is no API to modify policies. Are you interested in using an API to make minute adjustments, or is this more for backup/restore, or promoting a full set from a pre-prod test to production?

---

<div class="post-metadata">

**Author:** ![rgomez](https://avatars.discourse-cdn.com/v4/letter/r/43a26b/32.png) [@rgomez](https://community.sonatype.com/u/rgomez)\
**Post date:** [October 21, 2021, 11:16pm UTC](https://community.sonatype.com/t/update-policies-using-api/7516/3 "2021-10-21T23:16:19Z")

</div>

> [@jwhitehouse](#):
>
> Are you interested in using an API to make minute adjustments, or is this more for backup/restore, or promoting a full set from a pre-prod test to production?

If it’s the latter, I wrote a small script to batch import and export policies using the [undocumented “Import Policies” endpoints](https://help.sonatype.com/iqserver/managing/policy-management#PolicyManagement-ImportPoliciesImportingPolicies).

(Not sure if there’s an easier way, but there wasn’t when I wrote this.)

> **Source code (click to expand)**
>
> This is extracted from a larger script, so there may be a few minor errors. I also haven’t tested it in the last few versions of IQ.
> 
> ```python
> import json
> import logging
> import re
> from typing import Callable
> from pathlib import Path
> from requests import Response
> 
> logger = logging.getLogger( __file__ )
> 
> class IqConfig:
> 
> def __init__ (self, username: str, password: str, url: str = "http://localhost:8070"):
> # Configure the default HTTP client.
> self.url = url
> self.session = Session()
> self.session.auth = (username, password)
> 
> def import_policies(self):
> """
> Import a provided set of configuration.
> https://help.sonatype.com/iqserver/managing/policy-management#PolicyManagement-ReferencePolicySet
> """
> logger.info("[Policies] Importing policies...")
> 
> cwd = Path( __file__ ).resolve().parent
> policy_file = Path(cwd, "./iq-policies.json")
> with policy_file.open() as file:
> files = {"file": file}
> res = self._rest_api(
> lambda x: x.post(f"{self.url}/rest/policy/organization/ROOT_ORGANIZATION_ID/import", files=files)
> )
> logger.info("Response is: %s", res)
> 
> def export_policies(self):
> # Retrieve values from server.
> policies = self._rest_api(
> lambda x: x.get(f"{self.url}/rest/policy/organization/ROOT_ORGANIZATION_ID/applicable"),
> )
> labels = self._rest_api(
> lambda x: x.get(f"{self.url}/api/v2/labels/organization/ROOT_ORGANIZATION_ID/applicable"),
> )
> # Transform license groups into expected format.
> # Source:
> # { "id": "762ef2e2", "name": "Copyleft", "threatLevel": 7, "licenses": [] }
> licenseGroups = self._rest_api(
> lambda x: x.get(
> f"{self.url}/rest/licenseThreatGroup/organization/ROOT_ORGANIZATION_ID/applicable"
> ),
> )
> licenseGroups = licenseGroups["licenseThreatGroupsByOwner"][0]
> # Destination
> # { "id": "30b8026ddc654c838fde77dab08a3b18", "ownerId": "ROOT_ORGANIZATION_ID", "name": "Banned", "nameLowercaseNoWhitespace": "banned", "threatLevel": 10 }
> groups = []
> licenses = []
> for group in licenseGroups["licenseThreatGroups"]:
> group["ownerId"] = "ROOT_ORGANIZATION_ID"
> group["nameLowercaseNoWhitespace"] = re.sub(
> r"\s+", "", group["name"].lower(), flags=re.UNICODE
> )
> licenses.extend(group["licenses"])
> del group["licenses"]
> groups.append(group)
> 
> # licenses = __fetch(s, lambda x: x.get("/rest/license"))
> categories = self._rest_api(
> lambda x: x.get(
> f"{self.url}/api/v2/applicationCategories/organization/ROOT_ORGANIZATION_ID/applicable"
> ),
> )
> 
> # Format values
> export = {
> "policies": policies["policiesByOwner"][0]["policies"],
> "labels": labels["labelsByOwner"][0]["labels"],
> "licenseThreatGroups": groups,
> "licenseThreatGroupLicenses": licenses,
> "tags": categories["applicationCategoriesByOwner"][0]["applicationCategories"],
> "policyTags": policies["policiesByOwner"][0]["policyTags"],
> }
> 
> # Dump values
> with open("./iq-policies.json", "w") as fp:
> json.dump(export, fp)
> 
> def _rest_api(self, block: Callable[[Session], Response]) -> dict:
> """
> Makes a request against the IQ REST API and includes the CSRF token.
> This is required for the undocumented "/rest/..." API endpoints.
> """
> cookies = self.session.cookies.get_dict()
> if "CLM-CSRF-TOKEN" not in cookies:
> res = self.session.get("/")
> cookies = res.cookies.get_dict()
> 
> if res.status_code != 200:
> raise ValueError(f"Invalid response from server: {res.status_code}")
> elif "CLM-CSRF-TOKEN" not in cookies:
> raise ValueError(f"No CSRF Token returned: {cookies}")
> 
> self.session.headers.update({"X-CSRF-TOKEN": cookies["CLM-CSRF-TOKEN"]})
> res: Response = block(self.session)
> logger.info("Response is (%s): %s", res.status_code, res.text)
> res.raise_for_status()
> 
> try:
> return res.json()
> except:
> return None
> 
> ```

---

<div class="post-metadata">

**Author:** ![nikhil.nagesh.chodankar](https://avatars.discourse-cdn.com/v4/letter/n/65b543/32.png) [@nikhil.nagesh.chodankar](https://community.sonatype.com/u/nikhil.nagesh.chodankar)\
**Post date:** [October 22, 2021, 2:10am UTC](https://community.sonatype.com/t/update-policies-using-api/7516/4 "2021-10-22T02:10:57Z")

</div>

Hi @jwhitehouse we want to automate updating of nexus iq server policies via a jenkins pipeline. Hence, was looking out for any API call that can do it.

---

<div class="post-metadata">

**Author:** ![nikhil.nagesh.chodankar](https://avatars.discourse-cdn.com/v4/letter/n/65b543/32.png) [@nikhil.nagesh.chodankar](https://community.sonatype.com/u/nikhil.nagesh.chodankar)\
**Post date:** [October 25, 2021, 10:25am UTC](https://community.sonatype.com/t/update-policies-using-api/7516/5 "2021-10-25T10:25:51Z")

</div>

Also, to write the exact requirement - we would like to have the policies in the bitbucket and we would like to follow a change process whenever we want to update any policy. Once approved, then only Jenkins pipeline will be used to automate the updating of the policies.

---

<div class="post-metadata">

**Author:** ![jwhitehouse](https://yyz1.discourse-cdn.com/flex047/user_avatar/community.sonatype.com/jwhitehouse/32/187_2.png) [@jwhitehouse](https://community.sonatype.com/u/jwhitehouse)\
**Post date:** [November 8, 2021, 4:00pm UTC](https://community.sonatype.com/t/update-policies-using-api/7516/6 "2021-11-08T16:00:49Z")

</div>

Thanks for that use case @nikhil.nagesh.chodankar . This would be to make the config as code. One of the challenges is that ‘coding’ the config of policy is not simple.

I’d consider a way to have the UI for config and export the result, or connect to some storage (file, scm, etc) for change management and a human readable backup.

---

<div class="post-metadata">

**Author:** ![ingmar.vis](https://avatars.discourse-cdn.com/v4/letter/i/4af34b/32.png) [@ingmar.vis](https://community.sonatype.com/u/ingmar.vis)\
**Post date:** [November 6, 2022, 8:54pm UTC](https://community.sonatype.com/t/update-policies-using-api/7516/7 "2022-11-06T20:54:28Z")

</div>

Not simple sounds like fun 😀

I would like to add to this, we are also looking at ways of doing our policies and waivers as code, if there is already an idea floating around for this i would like to vote on it. Else i’ll create it myself.

Configuring through the UI and exporting it so it can be versioned, is flawed imho.

This process, for example when configuring via the UI in a lower environment, exporting it and subsequently importing it “as code” in a higher environment, is the opposite of what i would like to achieve with policy-as-code.

Full control, zero touch, full traceability, automation, unit tests ? The regular SDLC and CICD lifecycle for policies is much more interesting for us. Knowing which version of which policy created by who that triggered which violation onto which follow-up action was performed leading to what change in what piece of code etc is the way to go.

---

<div class="post-metadata">

**Author:** ![jeff.wise](https://yyz1.discourse-cdn.com/flex047/user_avatar/community.sonatype.com/jeff.wise/32/2421_2.png) [@jeff.wise](https://community.sonatype.com/u/jeff.wise)\
**Post date:** [November 7, 2022, 7:42pm UTC](https://community.sonatype.com/t/update-policies-using-api/7516/8 "2022-11-07T19:42:47Z")

</div>

Since ‘coding’ the config of policy is not simple, perhaps you can provide a CLI to view/modify a policy document. The CLI may be used in CI/CD workflows rather than rely on a web interface.

---

<div class="post-metadata">

**Author:** ![joris.klop](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@joris.klop](https://community.sonatype.com/u/joris.klop)\
**Post date:** [April 12, 2024, 12:51pm UTC](https://community.sonatype.com/t/update-policies-using-api/7516/9 "2024-04-12T12:51:03Z")

</div>

Hi Jamie, i know the response is REALLY late.

However, this subject seems really important, we think having the export as a baseline (and store that in SCM) is the way to go.

If there are any updates on the policies, there should be an easy way to export the policy towards SCM. I think this can be largely achieved by a export API endpoint, that will just read the policy. For now having the entire policy in code will not add value for our use case, as you outline creating it without errors seems complex and error prone.

Anyway, i will be testing with exporting the current policy by reverse engineering some UI elements, maybe the above example code will help with that one…

---

<div class="post-metadata">

**Author:** ![joris.klop](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@joris.klop](https://community.sonatype.com/u/joris.klop)\
**Post date:** [June 11, 2024, 3:27pm UTC](https://community.sonatype.com/t/update-policies-using-api/7516/10 "2024-06-11T15:27:36Z")

</div>

Minor update, just was able to export the root policy using GET request to https://IQ\_URL/rest/policy/organization/ROOT\_ORGANIZATION\_ID/export

From the UI there is an import that triggers POST to  
https://IQ\_URL/rest/policy/organization/ROOT\_ORGANIZATION\_ID/import?timestamp=linux\_timestamp\_var
