Skip to content

REST API Usage Guideline

Konstantin Müller edited this page Jul 25, 2023 · 4 revisions

Before you continue familiarize yourself with the Object-Fact-Model as this is the foundation of grafeo and its REST API.

Grafeo exposes a set of versioned REST APIs in order to interact with the system. The first version of the API v1 implements the Object-Fact-Model and is available for testing. The API is still under heavy development and it can change any time without further notice, however, as the application matures less breaking changes are expected. The API endpoints are fully documented with Swagger which contains a full description of each endpoint (including requests and responses). Head over to https://act-eu1.mnemonic.no/swagger/ to view the API documentation. Note that this is a read-only instance of grafeo such that it is only possible to perform non-manipulating requests (retrieving data), but it still displays the full API documentation.

Getting Started

You first have to create ObjectTypes and FactTypes which describe what kind of information can be added to the platform. Create two ObjectTypes ip and fqdn:

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Grafeo-User-ID: 1' -d '{
  "name": "ip",
  "validator": "TrueValidator"
}' 'http://localhost/v1/objectType'
curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Grafeo-User-ID: 1' -d '{
  "name": "fqdn",
  "validator": "TrueValidator"
}' 'http://localhost/v1/objectType'

A validator is used whenever an Object is stored in the platform to enforce a certain format on the Object's value. For simplicity the TrueValidator was chosen here. It will simply allow any value.

Next, create a FactType which describes the relationship between the ip and fqdn ObjectTypes:

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Grafeo-User-ID: 1' -d '{
  "name": "resolve",
  "validator": "TrueValidator",
  "relevantObjectBindings": [
    {
      "sourceObjectType": "6e2727da-f64c-45be-bf0c-8b3ef4fa61c8",
      "destinationObjectType": "5ea3774c-e09a-4553-87e4-79933c757699",
      "bidirectionalBinding": true
    }
  ] 
}' 'http://localhost/v1/factType'

The validator field has a similar meaning as the same field on ObjectType and the relevantObjectBindings field specifies that only Objects of type ip and fqdn can be used when creating a Fact of the resolve type. This will later be checked when a new resolve Fact is added to the platform. The values for sourceObjectType and destinationObjectType are the UUIDs from the previously created ip and fqdn ObjectTypes, respectively. They are returned by the responses to the create requests executed before, or can be retrieved using the GET /v1/objectType endpoint.

curl -X GET -H 'Accept: application/json' -H 'Grafeo-User-ID: 1' 'http://localhost/v1/objectType'

Now it is possible to add the first Fact to the platform:

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Grafeo-User-ID: 1' -d '{
  "type": "resolve",
  "sourceObject": "ip/140.82.118.4",
  "destinationObject": "fqdn/www.github.com",
  "bidirectionalBinding": true
}' 'http://localhost/v1/fact'

The Fact added here means that the IP address 140.82.118.4 resolved to the FQDN www.github.com. The request will be validated against the resolve FactType and the Fact will only be added if it passes that validation. For example, try setting sourceObject to the FQDN and destinationObject to the IP address. The request will be rejected with a 412 response code because the types for sourceObject and destinationObject do not fit the definition of the FactType. Also try sending the same add request multiple times and observe the response. This will not add multiple Facts, instead only the lastSeenTimestamp in the response will be updated. The platform ensures that the same Facts are not added multiple times, it will just record that the Fact has been seen again.

Some words about access control: Every Fact is owned by an organization and access to Facts is strictly controlled. A Fact can be public such that every user can see it. A Fact can have explicit access control which means that a user must be explicitly granted access to that Fact. The default access mode is role-based. In this mode a user can see the Fact if one has the general permission to view Facts for the organization owning the Fact, or if one was granted explicit access. More detailed information about access control is available here.

After creating the first Fact add more similar Facts. Afterwards use the POST /v1/fact/search endpoint to search through the stored Facts. The following query should return the first added Fact.

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Grafeo-User-ID: 1' -d '{
  "keywords": "github.com"
}' 'http://localhost/v1/fact/search'

Work with Facts

There are more endpoints which operate on Facts besides adding and fetching Facts. It is possible to add comments and retrieve them, to grant users access to non-public Facts, and to retract Facts. Retracting a Fact will add another Fact to the platform which states that the retracted Fact is not true. It acts as a revocation. Furthermore, the platform supports meta Facts - i.e. Facts about Facts. A meta Fact is a Fact directly bound to another Fact without the link via an Object. It adds more information directly to a Fact. There exists own endpoints for adding and retrieving meta Facts. Available meta Facts must be declared beforehand with FactTypes similar to how the resolve FactType has been defined above.

Work with Objects

Objects can not be added manually to the platform because they conceptually "exist" always. They are stored automatically the first time a Fact linking to them is added. Therefore it is only possible to retrieve Objects. They can either be fetched by UUID - GET /v1/object/uuid/{id} - or by type and value - GET /v1/object/{type}/{value}. Those endpoints do not only return the Object in the response but also a statistics field. This field contains statistics about all Facts bound to the Object (grouped by FactType). Additionally, it is possible to fetch Facts bound the a specific Object and to search for Objects using POST /v1/object/search. This search works similar to the Fact search endpoint above, only that it returns Objects instead of Facts. In order to be able to view an Object a user must have access to at least one Fact bound to the Object.

One very powerful functionality is implemented in the /v1/traverse endpoints. These endpoints allow to query the information stored in the platform using the Gremlin graph traversal language provided by Apache TinkerPop. This is possible because the Objects and Facts represent a graph where Objects are graph vertices and Facts graph edges. Below is a very simple example of a graph query.

curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Grafeo-User-ID: 1' -d '{
  "query": "g.out()"
}' 'http://localhost/v1/traverse/object/fqdn/www.github.com'

The query starts at a FQDN Object and moves via the Fact to the corresponding IP Object. This might be a toy example but graph queries are very powerful and allow to uncover previously unknown information which are impossible to detect by just looking at the raw data.

Grafeo-User-ID

The observant reader might have noticed that every request so far contained a special HTTP header: Grafeo-User-ID. With the default access controller this header must be sent with every request. It identifies the user and contains the user's numeric ID as defined in the access controller's properties file. Sending a different header value means executing the request as a different user. Note that this is not a security feature, it is meant to simplify testing and will be removed in the future.

Next

Explore the API documentation and uncover all the possibilities of grafeo.