REST API Usage Guideline
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.
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'
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.
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.
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.
Explore the API documentation and uncover all the possibilities of grafeo.