Lesson 2: Harry Potter meets Microsoft Copilot for Security

Rogier Dijkman
6 min readFeb 27, 2024

--

image created with CoPilot Designer

Lesson 2

In lesson 1, we tackled the fundamentals of making a plugin for Microsoft Security CoPilot. We started by crafting a manifest file and connecting it to an online OpenAPI Specification.

Now, we will dive into the simple setup of an OpenAPI specification file.
We will also create a template that we can utilize in upcoming lessons.
For the next example, we will use the previous API endpoint as in lesson 1 https://httpbin.org/

Documenting the API

When developers make an API (a tool for software to talk to other software), they usually provide instructions called documentation.
This explains what the API can do and how to use it.

The documentation follows a standard format set by the OpenAPI initiative, which is built on the Swagger Specification. Nowadays this documentation is called OpenAPI Specification (OAS) Throughout the following lessons we will use the abbreviation OAS.

OAS is like a blueprint or agreement for APIs. It explains what an API does, what information it needs (request parameters), and what it gives back (response objects), but it doesn’t include specific code details.

This means APIs built using OAS can talk to each other even if they’re written in different programming languages because OAS is designed to work with any language and can be easily understood by machines.

OpenAPI Specification (formaly swagger)

The OAS can contain many different attributes, but only a few are required for a custom plugin.
In our example we will use the following attributes:

  • Info Object
  • Server Object
  • Paths Object
  • Parameter Object (optional)

The Info object

In the info object is like a summary of key details about the API.
It usually includes things like the title, a brief description, the version number, and links to stuff like licenses and terms of service.

The only things that are required in there are the title and version. It's a good idea to include a description too. You can use markdown to format the description if you want.

info:
title: Wizard World Api
version: "0.1.0"

The Server object

In the servers object, we can list one or more main paths used in requests to the API.

This section is in array format, so each path needs to be specified separately, unlike the values in the info section.
The basepath is the part of the web address that comes before the specific endpoint. The only required property is the url

servers:
- url: https://api.example.com/
description: Harry Potter information provider

The Paths object

The paths object can be seen as a roadmap for the endpoints available within the API. It provided details on how to access the endpoints and what actions you can perform. Each endpoint is represented by a unique path within the paths object

To break this section a bit more down into digestible chunks, I will describe the most important parts.

  • path
  • HTTP methods
  • operation object …

path

The path is the relative URL of the API endpoint. It should start with a forward slash / and end with a double colon :

paths:
/houses:

HTTP Methods

Each path should specify one or more HTTP methods that are allowed to be used with the endpoint.
Each HTTP method represents a different action that can be performed on the endpoint.
Common HTTP methods are GET, POST, PUT, DELETE

paths:
/houses:
get:

Operation Object

For each HTTP method specified, there must be an associated operation object containing additional information about the operation.
Examples of these operation objects are parameters, request body, responses, etc.

The only required values are summary and the operation object responses
The summary field provides a brief, human-readable description of the endpoint.

In the responses section, we define the possible responses that the API can return when that endpoint is accessed. It contains the HTTP status codes and their corresponding descriptions.

Optionally, the responses section includes details about the response payload, like the format and schema definition.

paths:
/houses:
get:
operationId: gethouses
summary: Retrieve all Harry Potter houses
responses:
"200":
description: Success

Parameter Object

You don’t have to use the parameter object, but it’s handy when making a plugin for CoPilot(s). If you include the parameter object in the path item, the parameters will affect all actions on that path.

Alternatively, you can place parameters in the operations object, where they’ll only affect that specific action.

Depending on the API, the parameters can reside in different locations, indicated by the in field.

example parameter in path

paths:
/houses/{id}:
get:
parameters:
- name: id
in: path
required: true

In this example the parameter value is part the path:

https://api.example.com/houses/{id}

example parameter in query

paths:
/wizards:
get:
parameters:
- name: firstname
in: query

In this example the parameter value is part the query

https://api.example.com/wizards?firstname=George
  • NOTE: if the parameter is in the query, the name of the query parameter firstname is automatically added the the uri

Working Example

Now that we have a better understanding of the OAS (OpenAPI Specification), we can combine the previous information into a working example.

In this example we will use a public API for querying information about Harry Potter. We will add two different paths, one to collect information about and houses, and the other for searching a wizard.

openapi: 3.0.0

info:
title: Lesson 2 - OpenAPI Specification (swagger)
description: Lesson 2 - Basic request to lookup Harry Potter information.
version: "0.2.2"

servers:
- url: https://wizard-world-api.herokuapp.com/
paths:
/houses:
get:
operationId: gethouses
summary: Retrieve all Harry Potter houses
responses:
"200":
description: Success
/wizards:
get:
operationId: getwizards
summary: Retrieve Harry Potter wizards
parameters:
- in: query
name: FirstName
schema:
type: string
required: true
description: The name of the wizard
responses:
"200":
description: OK

The info field provides metadata about the API, including its title, description, and version. In this case, the API is for a lesson on using the OpenAPI Specification to look up Harry Potter information.

The servers field specifies the URL where the API is hosted. Here, the API is hosted at https://wizard-world-api.herokuapp.com/

The paths field describes the available paths and operations for the API. In this case, there are two paths: /houses and /wizards.

The /houses path supports a get operation, which retrieves all Harry Potter houses. The operationId is gethouses, and the summary provides a brief description of the operation.

The responses field describes the possible responses from the operation. Here, a 200 status code indicates a successful operation, with the description field providing a brief explanation of the response.

The /wizards path also supports a get operation, which retrieves Harry Potter wizards. The operationId is getwizards, and the summary provides a brief description of the operation

This operation requires a query parameter named FirstName, which is used to specify the name of the wizard.

The parameters field describes this requirement, including the name of the parameter, its schema (which specifies that the parameter must be a string), whether it's required (it is), and a description of the parameter.

The responses field describes the possible responses from the operation. Here, a 200 status code indicates a successful operation, with the description field providing a brief explanation of the response.

Testing the plugin

After we have added the plugin as described in lesson 1 it is time to test it.

Harry Potter Houses

  1. Open a new Session in Microsoft CoPilot for Security
  2. Let’s ask a question about the houses in Harry Potter: What houses are there in Harry Potter
  • NOTE: this prompt does not use the parameter object.

Harry Potter Wizards

  1. Open a new Session in Microsoft CoPilot for Security
  2. Let’s ask a question about a wizard: Give me some information about George Weasley
  • NOTE: this prompt does include a parameter value which is George

Summary

In Lesson 2, we explored creating plugins for Microsoft CoPilot for Security using OpenAPI Specification (OAS). We learned how to document APIs with OAS, focusing on key attributes like Info, Servers, Paths, and Parameters.
We also practiced creating a working example for querying Harry Potter information and tested it in CoPilot.

I didn’t include details about how the response should be structured because right now it doesn’t seem to make a difference in what we get back when we query an external API.
The other important observation is that I was not able to succesfully query and API if no OpenAPI Spec if published in the remote API.

--

--

Rogier Dijkman
Rogier Dijkman

Written by Rogier Dijkman

Microsoft Security MVP | Azure | GitHub | Cloud Security Architect | Marathoner | passionate about Microsoft Security

No responses yet