Get Approved/Blocked Audit Logs API

JFrog REST APIs

Products
JFrog Xray
Content Type
REST API
ft:sourceType
Paligo

Description: An API to get Approved/Blocked audit events for packages (allowing full export). 

Note: A synchronous REST API, to get Approved/Blocked audit events for packages.

Since: 3.82.x

Security: Requires a valid user with the "VIEW_POLICIES" permission.

Usage: GET /xray/api/v1/curation/audit/packages

Parameters:

Parameter

Type

Mandatory/Optional

Default Value

Description

order_by

string

optional

id

Order result by column name

direction

string

optional

desc

Order direction

num_of_rows

int

optional

100

Maximum number of rows in result, Valid values 1- 2000

created_at_start

datetime

optional

@todayDate - 7 days

Get logs starting from this date , date format example 2023-08-13T22:00:00.000Z

created_at_end

datetime

optional

@todayDate

Get logs that happen before this date

offset

int

optional

0

Get data starting from this offset

include_total

bolean

optional

false

Get total_count field in the result

Status Code

Description

200

OK

400

Bad request

404

Not found

Sample Request

GET /xray/api/v1/curation/audit/packages?
	order_by=id&
	direction=desc&
	num_of_rows=2&
	created_at_start=2023-07-20T22:00:00.000Z&
	created_at_end=2023-07-26T22:00:00.000Z&
	include_total=true&
            offset=0

Sample Response

200 OK
{
    "data": [
        {
            "id": 174,
            "created_at": "2023-08-30T05:45:52Z",
            "action": "blocked",
            "package_type": "Docker",
            "package_name": "pumevnezdiroorg/drupal",
            "package_version": "latest",
            "package_url": "https://registry-1.docker.io/v2/pumevnezdiroorg/drupal/manifests/latest",
            "reason": "Policy violations",
            "curated_repository_server_name": "",
            "curated_repository_name": "aviv-docker1",
            "curated_project": "default",
            "username": "admin",
            "user_mail": "",
            "origin_repository_server_name": "z0curdocktest",
            "origin_repository_name": "aviv-docker1",
            "origin_project": "default",
            "public_repo_url": "https://registry-1.docker.io",
            "public_repo_name": "Docker Hub",
            "policies": [
                {
                    "policy_name": "onlyOffical",
                    "policy_id": 3,
                    "dry_run": false,
                    "condition_name": "Image is not Docker Hub official",
                    "condition_category": "operational"
                }
            ]
        }
    ],
    "meta": {
        "total_count": 174,
        "result_count": 1,
        "next_offset": 1,
        "order_by": "id",
        "direction": "desc",
        "num_of_rows": 1,
        "offset": 0,
        "include_total": true,
        "include_explanation_and_recommendation": false,
        "created_at_start": "2023-08-23T05:48:32Z",
        "created_at_end": "2023-08-30T05:48:32Z"
    }
}

Python Example

import datetime


import requests
from requests.auth import HTTPBasicAuth


session = requests.Session()
auth = HTTPBasicAuth('username', 'password')


now = datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0)
print(now.isoformat(), 'start')
last_print = now


start = datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0)
curr = start - datetime.timedelta(days=30)


events_fetched = 0
while curr < start:
    offset = 0
    while True:
        now = datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0)
        if now != last_print:
            last_print = now
            print(now.isoformat(), 'created_at_start: %s, events_fetched: %d, offset: %d' % (curr.isoformat(), events_fetched, offset))
        response = session.get(
            'http://env_domain/xray/api/v1/curation/audit/packages',
            params={
                'include_total': 'false',
                'order_by': 'id',
                'direction': 'asc',
                'num_of_rows': 1000,
                'created_at_start': curr.isoformat(),
                'offset': offset,
            },
            auth=auth)
        response.raise_for_status()
        output = response.json()
        next_offset = output['meta']['next_offset']
        if not next_offset:
            break
        offset = next_offset
        events_fetched += output['meta']['result_count']
    curr += datetime.timedelta(days=7)


now = datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0)
print(now.isoformat(), 'fetched %d events' % events_fetched)