API Documentation

Complete API reference for ansible-inspec library and CLI.

Latest Update (v0.2.6): Version bump with documentation improvements.

v0.2.5: Fixed critical missing import statements that caused NameError in v0.2.4. All translator files now properly import re module for variable name sanitization.

v0.2.4: Added missing error handling and result tracking to assertion tasks. All assert tasks now include ignore_errors: True and register fields, enabling full compliance scans without early abortion and proper result collection for reporting.

v0.2.2: Added dynamic custom resource mapper that automatically translates custom InSpec resources to native Ansible modules. Also fixed InSpec parser value extraction to properly handle operators in assertions.

v0.2.1: Fixed critical translator field mismatch that prevented native translation.

v0.1.6: Fixed critical converter bug that caused 99% control loss when converting profiles with quoted control IDs.

Table of Contents


Installation

PyPI Installation

Docker Installation

See Docker Usage Guidearrow-up-right for detailed Docker instructions.


CLI Reference

Global Options

Global Flags:

  • --version - Show version and exit

  • --license - Show license information

  • --help, -h - Show help message

Commands

exec - Execute InSpec Profile

Run InSpec profiles on target systems using Ansible inventory.

Arguments:

  • PROFILE_PATH - Path to InSpec profile directory

Options:

  • -t, --target TARGET - Target specification (inventory file, host, or special target)

    • File path: /path/to/inventory.yml

    • Single host: user@hostname

    • Local: local://

    • Docker: docker://container_name

  • --reporter REPORTER - Output format for results

    • Single: json, html, junit, cli

    • Multiple: json:path.json html:path.html

    • Default: cli

  • --output PATH - Output file path for reports

  • --controls CONTROLS - Comma-separated list of control IDs to run

  • --tags TAGS - Comma-separated list of tags to filter controls

Examples:

convert - Convert InSpec Profile to Ansible Collection

Transform Ruby-based InSpec profiles into pure Ansible collections.

Arguments:

  • PROFILE_PATH - Path to InSpec profile directory or Supermarket profile name

Options:

  • -o, --output-dir DIR - Output directory for converted collection

    • Default: ./collections

  • -n, --namespace NAME - Ansible Galaxy namespace

    • Default: compliance

  • -c, --collection-name NAME - Collection name

    • Default: Derived from profile name

  • --no-build - Skip building the collection tarball

  • --force - Overwrite existing collection

  • --include-callback - Bundle compliance reporter callback plugin (enabled by default)

Examples:

supermarket - Interact with Chef Supermarket

Search and download compliance profiles from Chef Supermarket.

Subcommands:

search - Search for profiles

Options:

  • -l, --limit N - Limit results (default: 20)

  • -s, --sort FIELD - Sort by: name, downloads, updated (default: updated)

Examples:

info - Get profile details

Examples:

download - Download profile

Options:

  • -o, --output-dir DIR - Download destination (default: ./profiles)

Examples:


REST API Server

The ansible-inspec server provides a production-ready REST API for managing compliance testing workflows, VCS integration, and user authentication.

Base URL

Starting the Server

Authentication

The API supports two authentication methods:

  1. Azure AD OAuth2 - Enterprise SSO (recommended for production)

  2. Password-based - Local username/password authentication

All endpoints (except health check and auth endpoints) require authentication via JWT bearer tokens.

Authorization Header:

Role-Based Access Control (RBAC)

  • admin - Full access to all endpoints including user management

  • operator - Can manage job templates, jobs, and VCS repositories

  • viewer - Read-only access to jobs and templates


Authentication Endpoints

GET /health

Health check endpoint (no authentication required).

Response:

GET /api/v1

API information endpoint.

Response:

GET /api/v1/auth/login

Redirect to Azure AD OAuth2 login page.

Response:

  • 302 Redirect to Microsoft login page

POST /api/v1/auth/password-login

Login with username and password.

Request Body:

Response:

Status Codes:

  • 200: Success

  • 401: Invalid credentials

GET /api/v1/auth/callback

OAuth2 callback endpoint for Azure AD authentication.

Query Parameters:

  • code - Authorization code from Azure AD

  • state - State parameter for CSRF protection

Response:

GET /api/v1/auth/me

Get current authenticated user information.

Headers:

Response:

Status Codes:

  • 200: Success

  • 401: Unauthorized

POST /api/v1/auth/logout

Logout current user and invalidate token.

Response:


Job Template Endpoints

GET /api/v1/job-templates

List all job templates.

Query Parameters:

  • limit (int, optional): Maximum results (default: 100)

  • offset (int, optional): Pagination offset (default: 0)

Required Role: viewer

Response:

POST /api/v1/job-templates

Create a new job template.

Required Role: operator

Request Body:

Response:

Status Codes:

  • 201: Created

  • 400: Invalid input

  • 401: Unauthorized

  • 403: Forbidden

GET /api/v1/job-templates/{template_id}

Get a specific job template by ID.

Required Role: viewer

Response:

Status Codes:

  • 200: Success

  • 404: Template not found

PUT /api/v1/job-templates/{template_id}

Update a job template.

Required Role: operator

Request Body:

Response:

Status Codes:

  • 200: Success

  • 404: Template not found

  • 400: Invalid input

DELETE /api/v1/job-templates/{template_id}

Delete a job template.

Required Role: admin

Status Codes:

  • 204: No Content (success)

  • 404: Template not found

POST /api/v1/job-templates/{template_id}/launch

Launch a job from a template.

Required Role: operator

Request Body:

Response:

Status Codes:

  • 201: Created

  • 404: Template not found


Job Endpoints

GET /api/v1/jobs

List all jobs with optional filtering.

Query Parameters:

  • limit (int): Maximum results (default: 100)

  • offset (int): Pagination offset (default: 0)

  • status (string): Filter by status (pending, running, completed, failed)

  • template_id (string): Filter by template ID

Required Role: viewer

Response:

POST /api/v1/jobs

Create and execute a new job.

Required Role: operator

Request Body:

Response:

Status Codes:

  • 201: Created

  • 404: Template not found

GET /api/v1/jobs/{job_id}

Get detailed job information and results.

Required Role: viewer

Response:

Status Codes:

  • 200: Success

  • 404: Job not found


VCS Credential Endpoints

POST /api/v1/vcs/credentials

Create a new VCS credential for repository authentication.

Required Role: admin

Request Body:

Alternative with SSH:

Alternative with username/password:

Response:

Note: Credentials are encrypted at rest using Fernet symmetric encryption.

Status Codes:

  • 201: Created

  • 501: Encryption not configured

GET /api/v1/vcs/credentials

List all VCS credentials (without showing sensitive data).

Required Role: operator

Response:

DELETE /api/v1/vcs/credentials/{credential_id}

Delete a VCS credential.

Required Role: admin

Status Codes:

  • 204: No Content (success)

  • 404: Credential not found


VCS Repository Endpoints

POST /api/v1/vcs/repositories

Register a VCS repository for automatic profile synchronization.

Required Role: admin

Request Body:

Response:

Status Codes:

  • 201: Created

  • 400: Repository already exists

  • 501: VCS not enabled

GET /api/v1/vcs/repositories

List all registered VCS repositories.

Required Role: operator

Response:

POST /api/v1/vcs/repositories/{repo_name}/sync

Manually trigger repository synchronization.

Required Role: operator

Response:

Status Codes:

  • 200: Success

  • 404: Repository not found

  • 501: VCS not enabled

DELETE /api/v1/vcs/repositories/{repo_name}

Delete a VCS repository configuration (does not delete synced profiles).

Required Role: admin

Status Codes:

  • 204: No Content (success)

  • 404: Repository not found

GET /api/v1/vcs/repositories/{repo_name}/history

Get synchronization history for a repository.

Query Parameters:

  • limit (int): Maximum results (default: 50)

Required Role: viewer

Response:

GET /api/v1/vcs/repositories/{repo_name}/files

List all files in a synced repository.

Required Role: viewer

Response:

Status Codes:

  • 200: Success

  • 400: Repository not synced yet

  • 404: Repository not found

GET /api/v1/vcs/repositories/{repo_name}/files/{file_path}

Get content of a specific file from a synced repository.

Required Role: viewer

Response:

Status Codes:

  • 200: Success

  • 400: Invalid file path or binary file

  • 404: File not found


Webhook Endpoints

POST /api/v1/webhooks/github/{repo_name}

GitHub webhook handler for push events.

Headers:

Request Body: GitHub webhook payload

Response:

Status Codes:

  • 200: Success

  • 401: Invalid signature

  • 501: Webhooks not enabled

Configuration:

  1. Go to repository Settings → Webhooks

  2. Add webhook URL: http://your-server:8080/api/v1/webhooks/github/{repo_name}

  3. Content type: application/json

  4. Secret: Set WEBHOOK_SECRET environment variable

  5. Events: Select "Just the push event"

POST /api/v1/webhooks/gitlab/{repo_name}

GitLab webhook handler for push events.

Headers:

Request Body: GitLab webhook payload

Response:

Status Codes:

  • 200: Success

  • 401: Invalid token

  • 501: Webhooks not enabled

Configuration:

  1. Go to repository Settings → Webhooks

  2. Add webhook URL: http://your-server:8080/api/v1/webhooks/gitlab/{repo_name}

  3. Secret token: Set WEBHOOK_SECRET environment variable

  4. Trigger: Select "Push events"


User Management Endpoints

GET /api/v1/users

List all users (admin only).

Required Role: admin

Response:

PUT /api/v1/users/{user_id}

Update user roles and status (admin only).

Required Role: admin

Request Body:

Response:

Status Codes:

  • 200: Success

  • 404: User not found


Monitoring Endpoints

GET /api/v1/storage/validation-status

Get hybrid storage validation status (admin only, hybrid mode only).

Required Role: admin

Response:

Status Codes:

  • 200: Success

  • 400: Not using hybrid storage

GET /metrics

Prometheus metrics endpoint (no authentication required).

Response: Prometheus text format


API Examples

Complete Workflow Example

Python Client Example


Python API

Basic Usage


Core Classes

ExecutionConfig

Configuration for InSpec profile execution.

Attributes:

  • profile_path (str): Path to InSpec profile directory

  • target (str): Target specification

  • reporter (str): Output format (json, html, junit, cli)

  • output_path (Optional[str]): Path for report output

  • controls (Optional[List[str]]): List of control IDs

  • tags (Optional[List[str]]): List of tags to filter

ExecutionResult

Results from InSpec profile execution.

Example:

Runner

Execute InSpec profiles.

Methods:

  • run() -> ExecutionResult - Execute the profile and return results

ProfileConverter

Convert InSpec profiles to Ansible collections.

Parameters:

  • profile_path (str): Path to InSpec profile

  • output_dir (str): Output directory for collection

  • namespace (str): Ansible Galaxy namespace

  • collection_name (Optional[str]): Collection name (auto-generated if None)

  • force (bool): Overwrite existing collection

  • build (bool): Build collection tarball

Methods:

  • convert() -> str - Convert profile, returns collection path

  • build() -> str - Build collection tarball, returns tarball path

Example:


Reporters

InSpec JSON Reporter

Generate InSpec-compatible JSON reports.

Classes:

InSpecJSONReport

Main report container.

Attributes:

  • version (str): InSpec version

  • profiles (List[InSpecProfile]): List of profiles

  • platform (InSpecPlatform): Platform information

  • statistics (InSpecStatistics): Execution statistics

  • errors (List[str]): Execution errors

Methods:

  • to_dict() -> Dict - Convert to dictionary

  • to_json(indent: int = 2) -> str - Generate JSON string

  • save(path: str, indent: int = 2) -> None - Save to file

InSpecControl

Represents a single control.

Attributes:

  • id (str): Control ID

  • title (str): Control title

  • desc (str): Description

  • impact (float): Impact score (0.0 - 1.0)

  • tags (Dict): Tags

  • code (str): Control code

  • source_location (Dict): Source file location

  • results (List[Dict]): Test results

InSpecProfile

Represents an InSpec profile.

Attributes:

  • name (str): Profile name

  • title (str): Profile title

  • version (str): Version

  • summary (str): Summary

  • controls (List[InSpecControl]): Controls

InSpecPlatform

Platform information.

Attributes:

  • name (str): Platform name

  • release (str): Release version

  • target_id (str): Target identifier

InSpecStatistics

Execution statistics.

Attributes:

  • duration (float): Execution duration in seconds

  • controls (Dict): Control counts

HTML Reporter

Generate interactive HTML reports.

HTML Features:

  • Interactive dashboard

  • Control filtering

  • Pass/fail statistics

  • Color-coded results

  • Execution error section

  • Responsive design

JUnit Reporter

Generate JUnit XML for CI/CD integration.

JUnit Features:

  • Test suite per profile

  • Test case per control

  • Failure details

  • Execution timing

  • CI/CD compatible


Converters

Profile Conversion

The converter translates InSpec profiles (Ruby DSL) into Ansible collections with native tasks.

Key Features (v0.1.6):

  • Fixed Critical Bug: Control ID regex now properly handles quotes in control IDs

    • Previous versions failed on CIS benchmark controls like "1.1.1 (L1) Ensure 'password history' is set"

    • Now successfully converts all 358 controls instead of only 4 (99% improvement)

  • Sanitized Variable Names: Automatically converts control IDs to valid Ansible variable names

    • Example: "2.2.27 (L1) Ensure...""inspec_2_2_27_L1_Ensure"

  • Custom Resources: Detects and converts InSpec custom resources to Ansible modules

  • Native Modules: Prefers Ansible native modules when available (file, service, package, etc.)

Profile Structure Analysis

Control ID Handling

The converter properly handles complex control IDs from compliance frameworks:

Custom Resource Handling

The converter automatically detects and converts custom InSpec resources:

Conversion Workflow


Bug Fixes and Testing

Bug #1: Control ID Regex Pattern Fix (v0.1.6)

Severity: CRITICAL (P0) Status: Fixed Date: 2026-01-11

Problem

The InSpec profile converter was only converting 4 out of 358 controls (99% loss) from CIS benchmark profiles. The root cause was a regex pattern that failed to match control IDs containing single quotes.

Root Cause

The character class [^'\"]+ means "match any character EXCEPT quotes", causing the pattern to stop at the first quote inside the control ID:

Solution

Uses backreference \1 to match the same quote type that opened the string:

  • (['\"]) - Capture opening quote (group 1)

  • (.+?) - Capture control ID with any characters (group 2)

  • \1 - Match the SAME quote that opened the string

  • Control ID moved from group(1) to group(2)

  • Control body moved from group(2) to group(3)

Impact

  • Before: 4 controls converted (1.1% success rate)

  • After: 358 controls converted (100% success rate)

  • Improvement: 354 additional controls (8,850% increase)

Testing

The fix includes comprehensive regression tests:

Verification

To verify the fix works on your profiles:

References

  • Fixed Files: lib/ansible_inspec/converter.py (lines 169-172, 196-198)

  • Test Coverage: tests/test_converter.py (lines 178-285)


Examples

Example 1: Local Compliance Check

Example 2: Multi-Host Compliance

Example 3: Convert and Deploy

Example 4: CI/CD Integration

Example 5: Custom Reporting

Example 6: Chef Supermarket Integration


Configuration

Environment Variables

  • ANSIBLE_INSPEC_REPORTER - Default reporter format

  • ANSIBLE_INSPEC_OUTPUT_DIR - Default output directory

  • ANSIBLE_CONFIG - Ansible configuration file

  • ANSIBLE_INVENTORY - Default inventory file

Ansible Configuration


Error Handling


Support and Resources

  • Documentation: https://github.com/Htunn/ansible-inspec#readme

  • PyPI: https://pypi.org/project/ansible-inspec/

  • Docker Hub: https://hub.docker.com/r/htunnthuthu/ansible-inspec

  • Issues: https://github.com/Htunn/ansible-inspec/issues

  • Changelog: https://github.com/Htunn/ansible-inspec/blob/main/CHANGELOG.md


License

GPL-3.0-or-later. See LICENSEarrow-up-right for details.

Last updated