Examples¶
Custom Metric Examples¶
Note
Available in 5.4+ version of the ThreatConnect API.
- Direct Access:
resource = tcex.resources.CustomMetric(tcex)
- Dynamic Access:
resource = tcex.resource('CustomMetric')
Read Metric Configs¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('CustomMetric')
results = resource.request()
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | {
"status": "Success",
"data": {
"resultCount": 3,
"customMetricConfig": [
{
"id": 2,
"name": "Block Firewall Playbook Executions",
"dataType": "Sum",
"interval": "Hourly",
"keyedValues": false,
"description": "Execution count for HTTP trigger on Block Firewall"
},
{
"id": 3,
"name": "My Custom Metric",
"dataType": "Sum",
"interval": "Hourly",
"keyedValues": true,
"description": "A sum of all occurrences per Indicator Source"
}
]
}
}
|
Create Metric Config¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('CustomMetric')
resource.http_method = 'POST'
body = {
'name': 'My Custom Metric',
'dataType': 'Sum',
'interval': 'Hourly',
'keyedValues': true,
'description': 'A sum of all occurrences per Indicator Source'
}
results = resource.request()
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"status": "Success",
"data": {
"customMetricConfig": {
"id": 3,
"name": "My Custom Metric",
"dataType": "Sum",
"interval": "Hourly",
"keyedValues": true,
"description": "A sum of all occurrences per Indicator Source"
}
}
}
|
Read Metric Config (by ID)¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('CustomMetric')
resource.resource_id(3)
results = resource.request()
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"status": "Success",
"data": {
"customMetricConfig": {
"id": 3,
"name": "My Custom Metric",
"dataType": "Sum",
"interval": "Hourly",
"keyedValues": true,
"description": "A sum of all occurrences per Indicator Source"
}
}
}
|
Read Metric Config (by Name)¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('CustomMetric')
resource.resource_name('My Custom Metric')
results = resource.request()
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"status": "Success",
"data": {
"customMetricConfig": {
"id": 3,
"name": "My Custom Metric",
"dataType": "Sum",
"interval": "Hourly",
"keyedValues": true,
"description": "A sum of all occurrences per Indicator Source"
}
}
}
|
Update Metric Config¶
Note
Both the Metric ID and Metric Name can be used via the resource_id()
or resource_name
methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('CustomMetric')
resource.resource_id(3)
resource.http_method = PUT
body = {
'name': 'My Custom Metric',
'dataType': 'Sum',
'interval': 'Hourly',
'keyedValues': true,
'description': '(updated) A sum of all occurrences per Indicator Source'
}
results = resource.request()
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"status": "Success",
"data": {
"customMetricConfig": {
"id": 3,
"name": "My Custom Metric",
"dataType": "Sum",
"interval": "Hourly",
"keyedValues": true,
"description": "(updated) A sum of all occurrences per Indicator Source"
}
}
}
|
Create Metric Data¶
Note
The weight parameter is optional.
Important
Creating metrics will return a 204 by default with no Data. To get updated Metrics use the returnValue=true query parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('CustomMetric')
resource.http_method = 'POST'
resource.data(3)
body = {
"value": 1,
"weight": 1
}
resource.body = json.dumps(body)
results = resource.request()
print(results.get('status_code'))
if __name__ == "__main__":
main()
|
Response¶
No response returned.
Create Metric Data (with returnValue)¶
Note
The weight parameter is optional.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('CustomMetric')
resource.http_method = 'POST'
resource.data(3, True)
body = {
"name": "blue",
"value": 1,
"weight": 1
}
results = resource.request()
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
The response contains the processed results for the reporting period. For example if the Metric configured for a sum over a 1 hour period and this was the second value of 1 posted the response value would be 2.
1 2 3 4 | {
"value": 2,
"date": "2017-10-02T20:00:00-04:00"
}
|
Data Store Examples¶
- Direct Access:
resource = tcex.resources.DataStore(tcex)
- Dynamic Access:
resource = tcex.resource('DataStore')
Create Entry¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import json
from datetime import datetime
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.DataStore(tcex)
body = {'one': 1}
results = resource.create('local', 'tcex', 1, json.dumps(body))
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 | {
"_type": "24$tcex",
"created": true,
"_shards": {
"successful": 1,
"failed": 0,
"total": 2
},
"_version": 1,
"_index": "$local",
"_id": "1"
}
|
Read Entry¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import json
from datetime import datetime
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.DataStore(tcex)
results = resource.read('local', 'tcex', 1)
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 | {
"_type": "24$tcex",
"_source": {
"one": 1
},
"_index": "$local",
"_version": 1,
"found": true,
"_id": "1"
}
|
Update Entry¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import json
from datetime import datetime
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.DataStore(tcex)
body = {'one': 1, 'two', 2}
results = resource.update('local', 'tcex', 1, json.dumps(body))
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 | {
"_type": "24$tcex",
"created": false,
"_shards": {
"successful": 1,
"failed": 0,
"total": 2
},
"_version": 2,
"_index": "$local",
"_id": "1"
}
|
Delete Entry¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import json
from datetime import datetime
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.DataStore(tcex)
results = resource.delete('local', 'tcex', 1)
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 | {
"_type": "24$tcex",
"_shards": {
"successful": 1,
"failed": 0,
"total": 2
},
"_index": "$local",
"_version": 3,
"found": true,
"_id": "1"
}
|
Indicator Resource Examples¶
Resource Type | Class |
---|---|
Indicator Direct | resource = tcex.resources.Indicator(tcex) |
Indicator Dynamic | resource = tcex.resource(‘Indicator’) |
Address Direct | resource = tcex.resources.Address(tcex) |
Address Dynamic | resource = tcex.resource(‘Address’) |
EmailAddress Direct | resource = tcex.resources.EmailAddress(tcex) |
EmailAddress Dynamic | resource = tcex.resource(‘EmailAddress’) |
File Direct | resource = tcex.resources.File(tcex) |
File Dynamic | resource = tcex.resource(‘File’) |
Host Direct | resource = tcex.resources.Host(tcex) |
Host Dynamic | resource = tcex.resource(‘Host’) |
URL Direct | resource = tcex.resources.URL(tcex) |
URL Dynamic | resource = tcex.resource(‘URL’) |
Note
Custom Indicator types can only be accessed via the Dynamic method.
Retrieve All Indicators¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.Indicator(tcex)
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
for results in resource: # pagination
if results.get('status') == 'Success':
print(json.dumps(results.get('data', []), indent=4))
else:
warn = 'Failed retrieving result during pagination.'
tcex.log.error(warn)
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | [{
"rating": 5.0,
"confidence": 100,
"dateAdded": "2017-02-23T20:23:59Z",
"description": "Create via Playbook",
"threatAssessConfidence": 100.0,
"lastModified": "2017-03-02T19:05:03Z",
"threatAssessRating": 5.0,
"webLink": "https://app.threatconnect.com/auth/indicators/details/address.xhtml?address=1.1.1.4&owner=Acme+Corp",
"summary": "1.1.1.4",
"ownerName": "Acme Corp",
"type": "Address",
"id": 632128
},
{
"rating": 5.0,
"confidence": 100,
"dateAdded": "2017-02-21T16:52:15Z",
"description": "Test Description #5",
"threatAssessConfidence": 77.5,
"lastModified": "2017-02-21T00:00:00Z",
"threatAssessRating": 5.0,
"webLink": "https://app.threatconnect.com/auth/indicators/details/customIndicator.xhtml?id=603903&owner=Acme+Corp",
"summary": "HKEY_LOCAL_MACHINE : my-registry-key : REG_DWORD",
"ownerName": "Acme Corp",
"type": "Registry Key",
"id": 603903
},
<... snipped>
]
|
Retrieve Specific Indicator¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('Address')
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
resource.resource_id('1.1.1.4') # Optional
results = resource.request()
print(json.dumps(results.get('data'), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | {
"rating": 5.0,
"confidence": 100,
"dateAdded": "2017-02-23T20:23:59Z",
"description": "Create via Playbook",
"threatAssessConfidence": 100.0,
"lastModified": "2017-03-02T19:05:03Z",
"threatAssessRating": 5.0,
"webLink": "https://app.threatconnect.com/auth/indicators/details/address.xhtml?address=1.1.1.4&owner=Acme+Corp",
"ip": "1.1.1.4",
"owner": {
"type": "Organization",
"id": 2,
"name": "Acme Corp"
},
"id": 632128
}
|
Retrieve Filtered Indicators¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('Indicator')
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
resource.add_filter('rating', '>', 1)
resource.add_filter('confidence', '>', 50)
for results in resource: # pagination
if results.get('status') == 'Success':
print(json.dumps(results.get('data'), indent=4))
else:
warn = 'Failed retrieving result during pagination.'
tcex.log.error(warn)
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | [{
"rating": 5.0,
"confidence": 100,
"dateAdded": "2017-02-23T20:23:59Z",
"description": "Create via Playbook",
"threatAssessConfidence": 100.0,
"lastModified": "2017-03-02T19:05:03Z",
"threatAssessRating": 5.0,
"webLink": "https://app.threatconnect.com/auth/indicators/details/address.xhtml?address=1.1.1.4&owner=Acme+Corp",
"summary": "1.1.1.4",
"ownerName": "Acme Corp",
"type": "Address",
"id": 632128
},
{
"rating": 5.0,
"confidence": 100,
"dateAdded": "2017-02-21T16:52:15Z",
"description": "Test Description #5",
"threatAssessConfidence": 77.5,
"lastModified": "2017-02-21T00:00:00Z",
"threatAssessRating": 5.0,
"webLink": "https://app.threatconnect.com/auth/indicators/details/customIndicator.xhtml?id=603903&owner=Acme+Corp",
"summary": "HKEY_LOCAL_MACHINE : my-registry-key : REG_DWORD",
"ownerName": "Acme Corp",
"type": "Registry Key",
"id": 603903
},
<... snipped>
]
|
Indicator Associations¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('Indicator')
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
resource.add_filter('rating', '>', 1)
resource.add_filter('confidence', '>', 50)
for results in resource: # pagination
if results.get('status') == 'Success':
for indicator_data in results.get('data', []):
print(indicator_data.get('summary'))
iocs = [x for x in resource.indicators(i)] # get all iocs if more than 1
ioc = iocs[0].get('value') # only need the first one
# Get new Resource Object of Indicator Type
i_resource = tcex.resource(indicator_data.get('type'))
i_resource.resource_id(ioc) # set resource ID
ar = tcex.resource('Adversary') # Get Adversaries Instance
associations_resource = i_resource.associations(ar)
associations_results = associations_resource.request()
print(json.dumps(associations_results.get('data', []), indent=4))
else:
warn = 'Failed retrieving result during pagination.'
tcex.log.error(warn)
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | [{
"rating": 5.0,
"confidence": 100,
"dateAdded": "2017-02-23T20:23:59Z",
"description": "Create via Playbook",
"threatAssessConfidence": 100.0,
"lastModified": "2017-03-02T19:05:03Z",
"threatAssessRating": 5.0,
"webLink": "https://app.threatconnect.com/auth/indicators/details/address.xhtml?address=1.1.1.4&owner=Acme+Corp",
"summary": "1.1.1.4",
"ownerName": "Acme Corp",
"type": "Address",
"id": 632128
},
{
"rating": 5.0,
"confidence": 100,
"dateAdded": "2017-02-21T16:52:15Z",
"description": "Test Description #5",
"threatAssessConfidence": 77.5,
"lastModified": "2017-02-21T00:00:00Z",
"threatAssessRating": 5.0,
"webLink": "https://app.threatconnect.com/auth/indicators/details/customIndicator.xhtml?id=603903&owner=Acme+Corp",
"summary": "HKEY_LOCAL_MACHINE : my-registry-key : REG_DWORD",
"ownerName": "Acme Corp",
"type": "Registry Key",
"id": 603903
},
<... snipped>
]
|
Security Label Resource Examples¶
- Direct Access:
resource = tcex.resources.SecurityLabel(tcex)
- Dynamic Access:
resource = tcex.resource('SecurityLabel')
Retrieve All Security Labels¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.SecurityLabel(tcex)
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
for results in resource: # pagination
if results.get('status') == 'Success':
print(json.dumps(results.get('data', []), indent=4))
else:
warn = 'Failed retrieving result during pagination.'
tcex.log.error(warn)
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 | [{
"dateAdded": "2017-01-04T20:07:00Z",
"name": "TLP Green",
"description": "TLP Green"
},
{
"dateAdded": "2016-12-05T23:00:05Z",
"name": "TLP Red",
"description": "TLP Red"
}]
|
Retrieve Specific Security Label¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.SecurityLabel(tcex)
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
resource.resource_id('TLP Green') # Optional
results = resource.request()
print(json.dumps(results.get('data', []), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 | {
"dateAdded": "2017-01-04T20:07:00Z",
"name": "TLP Green",
"description": "TLP Green"
}
|
Retrieve Filtered Security Labels¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('SecurityLabel')
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
resource.add_filter('name', '^', 'TLP') # Optional
for results in resource: # pagination
if results.get('status') == 'Success':
print(json.dumps(results.get('data'), indent=4))
else:
warn = 'Failed retrieving result during pagination.'
tcex.log.error(warn)
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 | [{
"dateAdded": "2017-01-04T20:07:00Z",
"name": "TLP Green",
"description": "TLP Green"
},
{
"dateAdded": "2016-12-05T23:00:05Z",
"name": "TLP Red",
"description": "TLP Red"
}]
|
Tag Resource Examples¶
- Direct Access:
resource = tcex.resources.Tag(tcex)
- Dynamic Access:
resource = tcex.resource('Tag')
Retrieve All Tags¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.Tag(tcex)
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
for results in resource: # pagination
if results.get('status') == 'Success':
print(json.dumps(results.get('data', []), indent=4))
else:
warn = 'Failed retrieving result during pagination.'
tcex.log.error(warn)
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [{
"name": "APT",
"webLink": "https://api.threatconnect.com/auth/tags/tag.xhtml?tag=APT&owner=Acme+Corp"
},
{
"name": "AutoEnriched",
"webLink": "https://api.threatconnect.com/auth/tags/tag.xhtml?tag=AutoEnriched&owner=Acme+Corp"
},
{
"name": "China",
"webLink": "https://api.threatconnect.com/auth/tags/tag.xhtml?tag=China&owner=Acme+Corp"
},
{
"name": "CrimeWare",
"webLink": "https://api.threatconnect.com/auth/tags/tag.xhtml?tag=Crimeware&owner=Acme+Corp"
}]
|
Retrieve Specific Tag¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resources.Tag(tcex)
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
resource.resource_id('APT') # Optional
results = resource.request()
print(json.dumps(results.get('data', []), indent=4))
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 | {
"name": "APT",
"webLink": "https://api.threatconnect.com/auth/tags/tag.xhtml?tag=APT&owner=Acme+Corp"
}
|
Retrieve Filtered Tags¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | """ standard """
import json
from datetime import datetime
""" third party """
""" custom """
from tcex import TcEx
tcex = TcEx()
args = tcex.args
def main():
""" """
resource = tcex.resource('Tag')
resource.owner = 'Acme Corp'
resource.url = args.tc_api_path
resource.add_filter('name', '=', 'APT') # Optional
for results in resource: # pagination
if results.get('status') == 'Success':
print(json.dumps(results.get('data'), indent=4))
else:
warn = 'Failed retrieving result during pagination.'
tcex.log.error(warn)
if __name__ == "__main__":
main()
|
Response¶
1 2 3 4 | [{
"name": "APT",
"webLink": "https://api.threatconnect.com/auth/tags/tag.xhtml?tag=APT&owner=Acme+Corp"
}]
|