{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "http://axis.com/application-manifest-schema-v2.0.0.json",
    "type": "object",
    "title": "Application Manifest Schema",
    "description": "Schema describing a manifest given with an Axis application.",
    "additionalProperties": false,
    "required": [
        "schemaVersion",
        "acapPackageConf"
    ],
    "properties": {
        "$schema": {
            "type": "string",
            "format": "uri",
            "description": "URI of the manifest schema for validation"
        },
        "schemaVersion": {
            "type": "string",
            "pattern": "^2\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$",
            "description": "Specifies the application manifest schema version using three dot-separated integer numbers, which follow the semantic versioning rules for MAJOR, MINOR and PATCH version numbers."
        },
        "resources": {
            "type": "object",
            "description": "Host resources the application requires access to.",
            "additionalProperties": false,
            "minProperties": 1,
            "properties": {
                "dbus": {
                    "type": "object",
                    "description": "D-Bus resources on the host system that the application requires or desires access to.",
                    "additionalProperties": false,
                    "minProperties": 1,
                    "properties": {
                        "requiredMethods": {
                            "type": "array",
                            "description": "A list of D-Bus methods (given as strings) that are required by the application to be part of an API of the host system. If the methods are not present, the application is considered incompatible and will be rejected at installation. A wildcard '*' can be supplied at the end of a string, preceeded by a dot '.', to match all methods of a D-Bus interface.",
                            "items": {
                                "type": "string",
                                "oneOf": [
                                    {
                                        "type": "string",
                                        "pattern": "^com\\.axis\\.Graphics2(\\.\\*|\\.[a-zA-Z0-9_-]+(\\.\\*)?|(\\.[a-zA-Z0-9_-]+){1,2})$",
                                        "maxLength": 255
                                    },
                                    {
                                        "type": "string",
                                        "pattern": "^com\\.axis\\.HTTPConf1\\.VAPIXServiceAccounts1\\.GetCredentials$",
                                        "maxLength": 255
                                    },
                                    {
                                        "type": "string",
                                        "pattern": "^com\\.axis\\.Overlay2(\\.\\*|\\.[a-zA-Z0-9_-]+(\\.\\*)?|(\\.[a-zA-Z0-9_-]+){1,2})$",
                                        "maxLength": 255
                                    }
                                ]
                            }
                        },
                        "conditionalMethods": {
                            "type": "array",
                            "description": "A list of D-Bus methods (given as strings) desired by the application that may or may not be part of an API of the host system. If the methods are not present the application will still be installed. It is up to the application to handle the absence of the methods appropriately. A wildcard '*' can be supplied at the end of a string, preceeded by a dot '.', to match all methods of a D-Bus interface.",
                            "items": {
                                "type": "string",
                                "oneOf": [
                                    {
                                        "type": "string",
                                        "pattern": "^com\\.axis\\.Graphics2(\\.\\*|\\.[a-zA-Z0-9_-]+(\\.\\*)?|(\\.[a-zA-Z0-9_-]+){1,2})$",
                                        "maxLength": 255
                                    },
                                    {
                                        "type": "string",
                                        "pattern": "^com\\.axis\\.HTTPConf1\\.VAPIXServiceAccounts1\\.GetCredentials$",
                                        "maxLength": 255
                                    },
                                    {
                                        "type": "string",
                                        "pattern": "^com\\.axis\\.Overlay2(\\.\\*|\\.[a-zA-Z0-9_-]+(\\.\\*)?|(\\.[a-zA-Z0-9_-]+){1,2})$",
                                        "maxLength": 255
                                    }
                                ]
                            }
                        }
                    }
                },
                "deepLearningProcessor": {
                    "type": "object",
                    "description": "Specifies if the application requires or desires access to the Deep Learning Processing Unit (DLPU).",
                    "additionalProperties": false,
                    "properties": {
                        "enabled": {
                            "type": "boolean",
                            "description": "Enables DLPU access, if available."
                        },
                        "required": {
                            "type": "boolean",
                            "description": "If set to true, installation fails when DLPU access is not available. If set to false, installation proceeds regardless."
                        }
                    },
                    "required": [
                        "enabled",
                        "required"
                    ]
                },
                "linux": {
                    "type": "object",
                    "description": "Linux resources on the host system that the application requires or desires access to.",
                    "additionalProperties": false,
                    "minProperties": 1,
                    "properties": {
                        "user": {
                            "type": "object",
                            "description": "Dynamic user the application shall run as. The username of the dynamic user is determined at installation. If the application requires knowledge of the username it shall use the underlying OS functions to read it. Only one of dynamic user and static user (see acapPackageConf > setup > user) may be specified.",
                            "additionalProperties": false,
                            "minProperties": 1,
                            "properties": {
                                "groups": {
                                    "type": "array",
                                    "description": "A list of secondary groups (given as strings) the application user should belong to.",
                                    "items": {
                                        "type": "string",
                                        "enum": [
                                            "admin",
                                            "audiod",
                                            "gpu",
                                            "hidraw",
                                            "operator",
                                            "pipewire",
                                            "ptzadm",
                                            "sdk",
                                            "storage",
                                            "video",
                                            "viewer"
                                        ]
                                    }
                                },
                                "conditionalGroups": {
                                    "type": "array",
                                    "description": "A list of secondary groups (given as strings) the application user will belong to, if they exist and are allowed. It is up to the application to handle if the application user was not granted membership to one or more conditional groups.",
                                    "items": {
                                        "type": "string",
                                        "enum": [
                                            "admin",
                                            "audiod",
                                            "gpu",
                                            "hidraw",
                                            "operator",
                                            "pipewire",
                                            "ptzadm",
                                            "sdk",
                                            "storage",
                                            "video",
                                            "viewer"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "deviceDataHub_beta2": {
                    "type": "object",
                    "description": "Access to Device Data Hub for this ACAP application",
                    "additionalProperties": false,
                    "properties": {
                        "enabled": {
                            "type": "boolean",
                            "description": "Enables Device Data Hub for this ACAP application"
                        },
                        "accessControlList": {
                            "type": "array",
                            "description": "A list of entries that specify access rights",
                            "minItems": 0,
                            "maxItems": 256,
                            "items": {
                                "type": "object",
                                "description": "An entry that specifies access rights",
                                "additionalProperties": false,
                                "properties": {
                                    "topics": {
                                        "type": "array",
                                        "description": "A list of absolute topics in reverse domain format. The reverse domain prefix requires at least two segments (e.g. com.example), followed by at least one topic-specific segment. Topics starting with com.axis or containing wildcards (+ and #) are not allowed.",
                                        "minItems": 1,
                                        "maxItems": 64,
                                        "items": {
                                            "type": "string",
                                            "pattern": "^[a-z]{2,}(\\.[a-z0-9]+(-[a-z0-9]+)*)+(\\.[A-Za-z0-9_]+)+$",
                                            "maxLength": 256,
                                            "not": {
                                                "pattern": "^com\\.axis(\\.|$)"
                                            }
                                        }
                                    },
                                    "usernames": {
                                        "type": "array",
                                        "description": "A list of users",
                                        "minItems": 1,
                                        "maxItems": 64,
                                        "items": {
                                            "type": "string",
                                            "pattern": "^[a-z][a-z0-9_-]+$",
                                            "maxLength": 32
                                        }
                                    },
                                    "operations": {
                                        "type": "array",
                                        "description": "A list of operations that are valid on the specified topics for the specified users",
                                        "minItems": 1,
                                        "maxItems": 3,
                                        "items": {
                                            "type": "string",
                                            "enum": [
                                                "createDelete",
                                                "read",
                                                "write",
                                                "all"
                                            ]
                                        }
                                    }
                                },
                                "required": [
                                    "topics",
                                    "usernames",
                                    "operations"
                                ]
                            }
                        }
                    },
                    "required": [
                        "enabled"
                    ]
                },
                "overlay": {
                    "type": "object",
                    "description": "Access to overlay",
                    "additionalProperties": false,
                    "properties": {
                        "enabled": {
                            "type": "boolean",
                            "description": "Enables overlay, if available."
                        },
                        "required": {
                            "type": "boolean",
                            "description": "Fails installation if overlay is not available."
                        }
                    },
                    "required": [
                        "enabled"
                    ]
                }
            }
        },
        "acapPackageConf": {
            "type": "object",
            "description": "An ACAP package configuration object.",
            "additionalProperties": false,
            "properties": {
                "setup": {
                    "type": "object",
                    "description": "ACAP application identification and information settings.",
                    "additionalProperties": false,
                    "properties": {
                        "appName": {
                            "type": "string",
                            "pattern": "^[A-Za-z][A-Za-z0-9_]+$",
                            "maxLength": 26,
                            "description": "Name of the executable file."
                        },
                        "appId": {
                            "type": "string",
                            "pattern": "^[0-9]+$",
                            "description": "Application ID (provided by Axis). To retrieve an application ID, contact the Axis Technology Integration Partner Program support"
                        },
                        "architecture": {
                            "type": "string",
                            "enum": [
                                "all",
                                "aarch64",
                                "armv7hf"
                            ],
                            "description": "The target architecture(s) that the ACAP application supports. Will be set at build time if missing."
                        },
                        "compatibleOsVersions": {
                            "type": "array",
                            "description": "A list of version ranges of AXIS OS that this application has been designed to be compatible with. Starting with AXIS OS 12.10, the application will be prevented from being installed on devices with an AXIS OS version not within any of these ranges.",
                            "minItems": 1,
                            "items": {
                                "type": "object",
                                "description": "AXIS OS version range",
                                "additionalProperties": false,
                                "properties": {
                                    "min": {
                                        "type": "string",
                                        "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){0,2}$",
                                        "description": "Minimum version in this range. If only major version is given, the range includes all minor versions within that major version. If patch version is omitted, the range includes all patch versions within that minor version. If omitted, the SDK will automatically set it to the minimum AXIS OS version it supports, starting with ACAP SDK 12.10."
                                    },
                                    "max": {
                                        "type": "string",
                                        "pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){0,2}$",
                                        "description": "Maximum version in this range. If only major version is given, the range includes all minor versions within that major version. If patch version is omitted, the range includes all patch versions within that minor version."
                                    }
                                },
                                "required": [
                                    "min",
                                    "max"
                                ]
                            }
                        },
                        "friendlyName": {
                            "type": "string",
                            "pattern": "^(?!.*[\\n\\r]).*$",
                            "maxLength": 256,
                            "description": "User-friendly package name. The name that will be displayed e.g. in the embedded web pages."
                        },
                        "user": {
                            "type": "object",
                            "description": "Static user and group the application shall run as. Only one of dynamic user (see resources > linux > user) and static user may be specified.",
                            "additionalProperties": false,
                            "properties": {
                                "username": {
                                    "type": "string",
                                    "enum": [
                                        "sdk"
                                    ],
                                    "description": "Name of a user already existing on the device, used for application execution and file ownership."
                                },
                                "group": {
                                    "type": "string",
                                    "enum": [
                                        "admin",
                                        "audiod",
                                        "gpu",
                                        "hidraw",
                                        "operator",
                                        "pipewire",
                                        "ptzadm",
                                        "sdk",
                                        "storage",
                                        "video",
                                        "viewer"
                                    ],
                                    "description": "Name of a user group already existing on the device, used for application execution."
                                }
                            },
                            "required": [
                                "username",
                                "group"
                            ]
                        },
                        "runMode": {
                            "type": "string",
                            "enum": [
                                "once",
                                "respawn",
                                "respawnOnFailure",
                                "never"
                            ],
                            "description": "'once' means the application will be started at boot. 'respawn' means the application will be started at boot and restarted if it exits. 'respawnOnFailure' means the application will be started at boot and restarted if it exits with a non-zero exit code. 'never' means the application will never be started automatically, only through a VAPIX request."
                        },
                        "runOptions": {
                            "type": "string",
                            "pattern": "^[\\w /.=-]+$",
                            "description": "Optional application command line options"
                        },
                        "vendor": {
                            "type": "string",
                            "pattern": "^(?!.*[\\n\\r]).*$",
                            "description": "The company name of the provider and maintainer of the ACAP application."
                        },
                        "vendorUrl": {
                            "type": "string",
                            "format": "iri",
                            "description": "Link to the vendor home page."
                        },
                        "vendorId": {
                            "type": "string",
                            "pattern": "^[A-Fa-f0-9]{10}$",
                            "description": "The unique identifier of the provider and maintainer of the ACAP application."
                        },
                        "version": {
                            "type": "string",
                            "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
                            "description": "The ACAP application version, following the semantic versioning rules."
                        }
                    },
                    "required": [
                        "appName",
                        "architecture",
                        "compatibleOsVersions",
                        "runMode",
                        "vendor",
                        "vendorId",
                        "version"
                    ]
                },
                "installation": {
                    "type": "object",
                    "description": "ACAP application installation settings",
                    "additionalProperties": false,
                    "properties": {
                        "postInstallScript": {
                            "type": "string",
                            "pattern": "^[\\w.-]+$",
                            "description": "Optional script that will be run on the Axis product after ACAP package installation completion. This must be a shell script located in the package root."
                        }
                    }
                },
                "uninstallation": {
                    "type": "object",
                    "description": "ACAP application uninstallation settings",
                    "additionalProperties": false,
                    "properties": {
                        "preUninstallScript": {
                            "type": "string",
                            "pattern": "^[\\w.-]+$",
                            "description": "Optional script that will be run on the Axis product before uninstallation of the ACAP. This must be a shell script located in the package root."
                        }
                    }
                },
                "configuration": {
                    "type": "object",
                    "description": "ACAP application interaction setup.",
                    "additionalProperties": false,
                    "properties": {
                        "settingPage": {
                            "type": "string",
                            "pattern": "^[\\w.-]+$",
                            "description": "The name of the main embedded web page of the ACAP application. To be refered to when listing installed ACAP applications. Must be located in directory 'html' relative to application package root."
                        },
                        "httpConfig": {
                            "type": "array",
                            "description": "A list of web server configuration objects.",
                            "items": {
                                "type": "object",
                                "oneOf": [
                                    {
                                        "type": "object",
                                        "description": "A web server CGI configuration object.",
                                        "additionalProperties": false,
                                        "properties": {
                                            "type": {
                                                "type": "string",
                                                "enum": [
                                                    "transferCgi",
                                                    "fastCgi"
                                                ],
                                                "description": "CGI implementation type."
                                            },
                                            "name": {
                                                "type": "string",
                                                "pattern": "^(?!/)(?!\\.\\.?(/|$))((?!(/\\.\\./))[\\w/.-])+$",
                                                "description": "CGI path relative to application web root."
                                            },
                                            "access": {
                                                "type": "string",
                                                "enum": [
                                                    "admin",
                                                    "operator",
                                                    "viewer"
                                                ],
                                                "description": "Access policy for calling the CGI."
                                            }
                                        },
                                        "required": [
                                            "type",
                                            "name",
                                            "access"
                                        ]
                                    },
                                    {
                                        "type": "object",
                                        "description": "A web content object.",
                                        "additionalProperties": false,
                                        "properties": {
                                            "type": {
                                                "type": "string",
                                                "enum": [
                                                    "directory"
                                                ],
                                                "description": "Type of ACAP application web content. The type refers to the 'html' directory in the application package root."
                                            },
                                            "access": {
                                                "type": "string",
                                                "enum": [
                                                    "admin",
                                                    "operator",
                                                    "viewer"
                                                ],
                                                "description": "Access policy for viewing ACAP application web content, i.e. all files that are stored under 'html' directory in the application package root. Default access policy is 'admin'. Be aware that changing access policies will give general access to the web content."
                                            }
                                        },
                                        "required": [
                                            "type",
                                            "access"
                                        ]
                                    }
                                ]
                            }
                        },
                        "paramConfig": {
                            "type": "array",
                            "description": "A list of parameter configuration objects. It is possible to interact with these parameters using the Parameter API (axparameter), the [VAPIX API](https://www.axis.com/vapix-library/subjects/t10175981/section/t10036014/display) or from the settings web page of the ACAP application.",
                            "items": {
                                "type": "object",
                                "description": "A parameter object.",
                                "additionalProperties": false,
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "pattern": "^[A-Za-z][A-Za-z0-9_]*$",
                                        "maxLength": 32,
                                        "description": "Name of the parameter."
                                    },
                                    "default": {
                                        "type": "string",
                                        "pattern": "^.*$",
                                        "description": "Parameter default value."
                                    },
                                    "type": {
                                        "type": "string",
                                        "pattern": "^.*$",
                                        "description": "Parameter type definition string."
                                    }
                                },
                                "required": [
                                    "name",
                                    "default",
                                    "type"
                                ]
                            }
                        },
                        "reverseProxy": {
                            "type": "array",
                            "description": "A list of reverse proxy configuration objects.",
                            "items": {
                                "type": "object",
                                "oneOf": [
                                    {
                                        "type": "object",
                                        "description": "A reverse proxy unix domain socket object.",
                                        "additionalProperties": false,
                                        "properties": {
                                            "apiPath": {
                                                "type": "string",
                                                "pattern": "^[\\w\\-.+*?$(){}\\[\\]\\\\][\\w\\-.+*?$(){}\\[\\]\\\\/]*$",
                                                "description": "API path relative to the ACAP application home path."
                                            },
                                            "apiType": {
                                                "type": "string",
                                                "enum": [
                                                    "http",
                                                    "ws",
                                                    "fcgi"
                                                ],
                                                "description": "API protocol (http, web socket or fast cgi)."
                                            },
                                            "target": {
                                                "type": "string",
                                                "pattern": "^(unix:/)+[\\w/.-:]+$",
                                                "description": "Target path to a unix domain socket."
                                            },
                                            "access": {
                                                "type": "string",
                                                "enum": [
                                                    "admin",
                                                    "operator",
                                                    "viewer",
                                                    "anonymous"
                                                ],
                                                "description": "Access policy for calling the path."
                                            }
                                        },
                                        "required": [
                                            "apiPath",
                                            "apiType",
                                            "target",
                                            "access"
                                        ]
                                    },
                                    {
                                        "type": "object",
                                        "description": "A reverse proxy tcp object.",
                                        "additionalProperties": false,
                                        "properties": {
                                            "apiPath": {
                                                "type": "string",
                                                "pattern": "^[\\w\\-.+*?$(){}\\[\\]\\\\][\\w\\-.+*?$(){}\\[\\]\\\\/]*$",
                                                "description": "API path relative to the ACAP application home path."
                                            },
                                            "target": {
                                                "type": "string",
                                                "pattern": "^(http://|ws://|fcgi://)+[\\w/.-:]+$",
                                                "description": "Target path. FastCGI or URI (http or web socket)."
                                            },
                                            "access": {
                                                "type": "string",
                                                "enum": [
                                                    "admin",
                                                    "operator",
                                                    "viewer",
                                                    "anonymous"
                                                ],
                                                "description": "Access policy for calling the path."
                                            }
                                        },
                                        "required": [
                                            "apiPath",
                                            "target",
                                            "access"
                                        ]
                                    }
                                ]
                            }
                        }
                    }
                },
                "copyProtection": {
                    "type": "object",
                    "description": "ACAP application copy protection utilization",
                    "additionalProperties": false,
                    "properties": {
                        "method": {
                            "type": "string",
                            "enum": [
                                "none",
                                "axis",
                                "custom"
                            ],
                            "description": "Copy protection mechanism. If 'axis', appId property must be set, as appId is required for the Axis license."
                        }
                    },
                    "required": [
                        "method"
                    ]
                }
            },
            "required": [
                "setup"
            ]
        }
    }
}
