# Validation and security

Source: https://apigenie.pl/docs/reference/server/validation
Part of the reference of [apigenie-server](https://apigenie.pl/docs/reference/server.md).
Its other pages: [Responses](https://apigenie.pl/docs/reference/server/responses.md), [Scenarios and extensions](https://apigenie.pl/docs/reference/server/scenarios.md), [Scripts](https://apigenie.pl/docs/reference/server/scripts.md), [Document store](https://apigenie.pl/docs/reference/server/store.md), [Several services](https://apigenie.pl/docs/reference/server/services.md), [Contract testing (validating proxy)](https://apigenie.pl/docs/reference/server/contract-testing.md), [Session recording and replay](https://apigenie.pl/docs/reference/server/recording.md), [AsyncAPI](https://apigenie.pl/docs/reference/server/asyncapi.md), [Protobuf / gRPC](https://apigenie.pl/docs/reference/server/grpc.md), [GraphQL](https://apigenie.pl/docs/reference/server/graphql.md), [Configuration](https://apigenie.pl/docs/reference/server/configuration.md), [Dashboard and admin API](https://apigenie.pl/docs/reference/server/dashboard.md), [TLS](https://apigenie.pl/docs/reference/server/tls.md).

Requests are checked against their operation: path, query, header and cookie parameters in every
style, and JSON, XML, form and multipart bodies. A request that doesn't match is answered with 422
and the problems, a body that can't be parsed (JSON, XML, multipart) with 400, an unknown media type
with 415. Security
requirements are checked for presence (API keys, HTTP basic and bearer, OAuth2 and OpenID Connect
tokens; 401 with `WWW-Authenticate`), and against configured credentials in `enforce` mode (403).
Responses the mock makes are checked too: problems are logged and counted in
`X-Apigenie-Mock-Violations`, or answered with 500 under `--strict`.

Schemas' `format` values are checked as the
[OpenAPI format registry](/docs/reference/cli/formats) defines them, for the JSON types each
format applies to (`int8` ranges, `http-date`, `decimal`, `language`, ...);
`validation.formats: false` turns these checks off. Formats of your own, declared in
[`openapi.custom_formats`](/docs/reference/cli/configuration#openapicustom_formats) of the
configuration file, are accepted as they are, and an entry there naming a registry format
replaces that format's type and its check.

## XML bodies

Bodies of `application/xml`, `text/xml` and `+xml` media types are parsed as XML 1.0 with
namespaces, mapped to a JSON value as the schema's `xml` objects describe it, and checked against
the schema like JSON bodies; the mock, the validating proxy and `apigenie test` do the same, and
the mock and `apigenie test --generate` write XML the same way in reverse. For this schema

```yaml
Order:
  type: object
  xml: {name: order, namespace: "urn:orders", prefix: o}
  properties:
    id: {type: integer, xml: {nodeType: attribute}}   # OpenAPI 3.0/3.1: attribute: true
    customer: {$ref: "#/components/schemas/Customer"} # Customer has xml: {name: Buyer}
    note: {type: string, xml: {nodeType: cdata}}
    tags: {type: array, items: {type: string, xml: {name: tag}}}
    lines:
      type: array
      xml: {name: Lines, nodeType: element}           # 3.0/3.1: wrapped: true
      items: {$ref: "#/components/schemas/Line"}      # Line has xml: {name: Line}
```

the body is

```xml
<o:order xmlns:o="urn:orders" id="7">
  <Buyer><name>Ann</name></Buyer>
  <![CDATA[Leave at the <door>]]>
  <tag>a</tag><tag>b</tag>
  <Lines><Line sku="x"><quantity>2</quantity></Line></Lines>
</o:order>
```

- The root element is named by the schema's `xml.name`, else by the component a `$ref` points to;
  another name is a `xml-root` violation. A schema without either names no root.
- A property is a child element named by its `xml.name` (its own, or that of the schema it
  references), else by the property name. `nodeType: attribute` makes it an attribute, `text`
  and `cdata` the element's character data.
- An array's items repeat in the parent element, named by the items' `xml.name` or the property
  name; with `nodeType: element` (`wrapped: true`) they sit in a wrapper element.
- A declared `xml.namespace` must match; without one, elements are matched by local name in any
  namespace. An element with a property's local name in another namespace isn't that property: it
  is kept as `{namespace}name`, so the property is missing and `additionalProperties: false`
  reports the element.
- Child elements are written in the order the schema declares its properties, as XML Schema
  sequences require.
- Text becomes an integer, number, boolean or null where the schema allows it (white space around
  such values is ignored); `xsi:nil="true"` is null. Elements and attributes the schema doesn't
  declare are kept by local name, so `additionalProperties: false` reports them.
- A body that isn't well-formed is `malformed-xml` (`request.body.malformed`, answered with 400;
  `response.body.malformed`), with its line and column. Document type declarations are refused,
  so external entities and entity expansion are errors.

A SOAP service described in WSDL 1.1 is served after
[`apigenie convert --to openapi31`](/docs/reference/cli/convert#wsdl-11-input): the converted
document describes the SOAP envelopes with these `xml` objects.
