diff --git a/src/KPI Generator/KPI Generator.csproj b/src/KPI Generator/KPI Generator.csproj
index 037b55d6f69ab1fbe0e6b35f23aeb3c0ab239673..b74663d2503e5ae2003c2aadc097763b53e6ac74 100644
--- a/src/KPI Generator/KPI Generator.csproj	
+++ b/src/KPI Generator/KPI Generator.csproj	
@@ -21,9 +21,11 @@
 		<PackageReference Include="AutoMapper" Version="12.0.1" />
 		<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
 		<PackageReference Include="CommandLineParser" Version="2.9.1" />
-		<PackageReference Include="Coscine.ApiClient" Version="1.2.1" />
+		<PackageReference Include="Coscine.ApiClient" Version="1.3.0-issue-2666-admin0005" />
+		<PackageReference Include="dotNetRdf.Core" Version="3.1.1" />
 		<PackageReference Include="GitLabApiClient" Version="1.8.1-beta.5" />
 		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
+		<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
 		<PackageReference Include="NLog" Version="5.1.0" />
 		<PackageReference Include="NLog.Extensions.Logging" Version="5.2.0" />
 		<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
diff --git a/src/KPI Generator/Reportings/ApplicationProfile/ReturnObject.cs b/src/KPI Generator/Models/ApplicationProfileReport.cs
similarity index 66%
rename from src/KPI Generator/Reportings/ApplicationProfile/ReturnObject.cs
rename to src/KPI Generator/Models/ApplicationProfileReport.cs
index 6369623568ffb4c02f44ce096d5533aafa76fe59..7e517f97824547a01f1d5c705aadb4bc0044550a 100644
--- a/src/KPI Generator/Reportings/ApplicationProfile/ReturnObject.cs	
+++ b/src/KPI Generator/Models/ApplicationProfileReport.cs	
@@ -1,11 +1,11 @@
-namespace Coscine.KpiGenerator.Reportings.ApplicationProfile;
+namespace Coscine.KpiGenerator.Models;
 
 /// <summary>
 /// Object containing the JSON structure for the reporting
 /// </summary>
-public class ReturnObject
+public class ApplicationProfileReport
 {
-    public List<string?> Titles { get; set; } = new();
+    public List<string> Titles { get; set; } = new();
     public string Uri { get; set; } = null!;
     public string? Publisher { get; set; } = null!;
     public string? Rights { get; set; } = null!;
diff --git a/src/KPI Generator/Models/ConfigurationModels/KpiConfiguration.cs b/src/KPI Generator/Models/ConfigurationModels/KpiConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..489bd9dcbfa4e197852d1d7b55a848aec6771550
--- /dev/null
+++ b/src/KPI Generator/Models/ConfigurationModels/KpiConfiguration.cs	
@@ -0,0 +1,59 @@
+namespace Coscine.KpiGenerator.Models.ConfigurationModels;
+
+/// <summary>
+/// Represents the configuration settings for JSON Web Tokens (JWT) used in the application.
+/// </summary>
+public class KpiConfiguration
+{
+    /// <summary>
+    /// The section name in the configuration file.
+    /// </summary>
+    public static readonly string Section = "KpiConfiguration";
+
+    /// <summary>
+    /// Indicates whether the issuer should be validated during token validation.
+    /// </summary>
+    public ApplicationProfileKpi ApplicationProfileKpi { get; set; } = null!;
+
+    /// <summary>
+    /// Indicates whether the audience should be validated during token validation.
+    /// </summary>
+    public ProjectKpi ProjectKpi { get; set; } = null!;
+
+    /// <summary>
+    /// Indicates whether the lifetime should be validated during token validation.
+    /// </summary>
+    public ResourceKpi ResourceKpi { get; set; } = null!;
+
+    /// <summary>
+    /// Indicates whether the issuer signing key should be validated during token validation.
+    /// </summary>
+    public SystemKpi SystemKpi { get; set; } = null!;
+
+    /// <summary>
+    /// A list of valid issuers for the JWT.
+    /// </summary>
+    public UserKpi UserKpi { get; set; } = null!;
+}
+
+public record ApplicationProfileKpi(string FileName);
+
+public record Maintenance
+{
+    public string Url { get; init; } = null!;
+    public string Username { get; init; } = null!;
+    public string Password { get; init; } = null!;
+    public string BasicAuthToken { get; init; } = null!;
+}
+
+public record ProjectKpi(string FileName);
+
+public record ResourceKpi(string FileName);
+
+public record SystemKpi
+{
+    public string FileName { get; set; } = null!;
+    public Maintenance Maintenance { get; set; } = null!;
+}
+
+public record UserKpi(string FileName);
diff --git a/src/KPI Generator/Models/MaintenanceReport.cs b/src/KPI Generator/Models/MaintenanceReport.cs
new file mode 100644
index 0000000000000000000000000000000000000000..eaa24ab40331c485723615ae525a35905baaf0f7
--- /dev/null
+++ b/src/KPI Generator/Models/MaintenanceReport.cs	
@@ -0,0 +1,22 @@
+using System.Text.Json.Serialization;
+
+namespace Coscine.KpiGenerator.Models;
+
+public record MaintenanceReport
+{
+    [JsonPropertyName("id")]
+    public int Id { get; init; }
+    [JsonPropertyName("title")]
+    public string Title { get; init; } = null!;
+    [JsonPropertyName("short_message")]
+    public string ShortMessage { get; init; } = null!;
+    [JsonPropertyName("message")]
+    public string Message { get; init; } = null!;
+    [JsonPropertyName("status")]
+    public string Status { get; init; } = null!;
+    [JsonPropertyName("start_at")]
+    public DateTime? StartAt { get; init; } = null!;
+    [JsonPropertyName("end_at")]
+    public DateTime? EndAt { get; init; } = null!;
+}
+
diff --git a/src/KPI Generator/Models/SystemReport.cs b/src/KPI Generator/Models/SystemReport.cs
new file mode 100644
index 0000000000000000000000000000000000000000..45a0bb3535de90b0d289114e3ab0d16dc0fcaf18
--- /dev/null
+++ b/src/KPI Generator/Models/SystemReport.cs	
@@ -0,0 +1,9 @@
+namespace Coscine.KpiGenerator.Models;
+
+/// <summary>
+/// Object containing the JSON structure for the reporting
+/// </summary>
+public record SystemReport
+{
+    public IReadOnlyList<MaintenanceReport>? Banners { get; init; } = new List<MaintenanceReport>();
+}
\ No newline at end of file
diff --git a/src/KPI Generator/Program.cs b/src/KPI Generator/Program.cs
index 14901767dd2707d903ac377215ba5316cd6f17c4..0fe1c8d0adb0b9fce8d3184e9fec8ca3d4cc886e 100644
--- a/src/KPI Generator/Program.cs	
+++ b/src/KPI Generator/Program.cs	
@@ -1,5 +1,6 @@
 using CommandLine;
 using Coscine.KpiGenerator.Logging;
+using Coscine.KpiGenerator.Models.ConfigurationModels;
 using Coscine.KpiGenerator.Reportings.Project;
 using Coscine.KpiGenerator.Reportings.Resource;
 using GitLabApiClient;
@@ -39,8 +40,8 @@ public class Program
                 (ProjectReportingOptions opts) => _serviceProvider.GetRequiredService<ProjectReporting>().RunAsync(opts).Result,
                 (ResourceReportingOptions opts) => _serviceProvider.GetRequiredService<ResourceReporting>().RunAsync(opts).Result,
                 (UserReportingOptions opts) => _serviceProvider.GetRequiredService<UserReporting>().RunAsync(opts).Result,
-                //(ApplicationProfileReportingOptions opts) => _serviceProvider.GetRequiredService<ApplicationProfileReporting>().Run(opts),
-                //(SystemReportingOptions opts) => _serviceProvider.GetRequiredService<SystemReporting>().Run(opts),
+                (SystemReportingOptions opts) => _serviceProvider.GetRequiredService<SystemReporting>().RunAsync(opts).Result,
+                (ApplicationProfileReportingOptions opts) => _serviceProvider.GetRequiredService<ApplicationProfileReporting>().RunAsync(opts).Result,
                 HandleParseError
             );
 
@@ -82,9 +83,9 @@ public class Program
         configBuilder.Sources.Clear();
 
         // Add Consul as a configuration source
-        configBuilder
+        var configuration = configBuilder
             .AddConsul(
-                "coscine/Coscine.Api/appsettings",
+                "coscine/Coscine.Infrastructure/KpiGenerator/appsettings",
                 options =>
                 {
                     options.ConsulConfigurationOptions =
@@ -95,14 +96,18 @@ public class Program
                     options.OnLoadException = exceptionContext => exceptionContext.Ignore = true;
                 }
             )
-            .AddEnvironmentVariables();
-
-        // Build the configuration
-        var configuration = configBuilder.Build();
-
+            .AddEnvironmentVariables()
+            .Build();
+        
         var services = new ServiceCollection()
             .AddSingleton<IConfiguration>(configuration);
 
+        // Add the configuration to the service collection
+        services.Configure<KpiConfiguration>(settings =>
+        {
+            configuration.GetSection(KpiConfiguration.Section).Bind(settings);
+        });
+
         // Add logging
         services.AddLogging(builder =>
         {
@@ -122,8 +127,8 @@ public class Program
         services.AddTransient<ProjectReporting>();
         services.AddTransient<ResourceReporting>();
         services.AddTransient<UserReporting>();
-        //services.AddTransient<ApplicationProfileReporting>();
-        //services.AddTransient<SystemReporting>();
+        services.AddTransient<SystemReporting>();
+        services.AddTransient<ApplicationProfileReporting>();
 
         _serviceProvider = services.BuildServiceProvider();
     }
diff --git a/src/KPI Generator/Reportings/ApplicationProfile/ApplicationProfileReporting.cs b/src/KPI Generator/Reportings/ApplicationProfile/ApplicationProfileReporting.cs
index 9ed9a5260235ec34aeff63f02410c26b8749360d..5bec3716b8ac9eee06fa638e77876dd0f561d0cc 100644
--- a/src/KPI Generator/Reportings/ApplicationProfile/ApplicationProfileReporting.cs	
+++ b/src/KPI Generator/Reportings/ApplicationProfile/ApplicationProfileReporting.cs	
@@ -1,90 +1,107 @@
-//using Coscine.KpiGenerator.Utils;
-//using Microsoft.Extensions.Logging;
-//using Newtonsoft.Json;
-//using NLog.Extensions.Logging;
-//using VDS.RDF.Query;
-//using static KPIGenerator.Utils.CommandLineOptions;
-
-//namespace Coscine.KpiGenerator.Reportings.ApplicationProfile;
-
-//public class ApplicationProfileReporting : Reporting<ApplicationProfileReportingOptions>
-//{
-//    private readonly ILogger<ApplicationProfileReporting> _logger;
-
-//    public ApplicationProfileReporting(ApplicationProfileReportingOptions options) : base(options)
-//    {
-//        ReportingFileName = "application_profiles.json";
-//        _logger = LoggerFactory.Create(builder => builder.AddNLog()).CreateLogger<ApplicationProfileReporting>();
-//    }
-
-//    public override IEnumerable<ReportingFileObject> GenerateReportingAsync()
-//    {
-//        Console.WriteLine($" - {GetType().Name}: Begin reporting generation");
-//        _logger.LogInformation("{Name}: Begin reporting generation", GetType().Name);
-//        var reportingFiles = new List<ReportingFileObject>();
-//        var returnObjects = GetApplicationProfiles();
-
-//        // General File
-//        reportingFiles.Add(new ReportingFileObject
-//        {
-//            Path = GetReportingPathGeneral(ReportingFileName),
-//            Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjects, Formatting.Indented))
-//        });
-//        Console.WriteLine($" - {GetType().Name}: \"{GetReportingPathGeneral(ReportingFileName)}\" generated successfully");
-//        _logger.LogInformation("{Name}: Generated successfully. {reportingFiles}", GetType().Name, reportingFiles);
-
-//        Console.WriteLine();
-//        return reportingFiles;
-//    }
-
-//    private List<ReturnObject> GetApplicationProfiles()
-//    {
-//        var _applicationProfile = "applicationProfile";
-//        var _title = "title";
-//        var _publisher = "publisher";
-//        var _rights = "rights";
-//        var _license = "license";
-
-//        var returnObjects = new List<ReturnObject>();
-//        var queryString = new SparqlParameterizedString
-//        {
-//            CommandText = $@"PREFIX dcterms: <http://purl.org/dc/terms/>
-//                            SELECT DISTINCT * WHERE {{ 
-//                              ?{_applicationProfile} a <http://www.w3.org/ns/shacl#NodeShape> . 
-//                              OPTIONAL {{ ?{_applicationProfile} dcterms:{_title} ?{_title}.  }}
-//                              OPTIONAL {{ ?{_applicationProfile} dcterms:{_publisher} ?{_publisher} . }}
-//                              OPTIONAL {{ ?{_applicationProfile} dcterms:{_rights} ?{_rights} .  }}
-//                              OPTIONAL {{ ?{_applicationProfile} dcterms:{_license} ?{_license} .  }}
-//                            }}"
-//        };
-//        using var result = Helpers.WrapRequest(() => RdfStoreConnector.QueryEndpoint.QueryWithResultSet(queryString.ToString()));
-
-//        var grouped = result.GroupBy(ap => new
-//        {
-//            Uri = ap.Value(_applicationProfile).ToString(),
-//            Publisher = ap.HasValue(_publisher) && ap.Value(_publisher) is not null ? ap.Value(_publisher).ToString() : null,
-//            Rights = ap.HasValue(_rights) && ap.Value(_rights) is not null ? ap.Value(_rights).ToString() : null,
-//            License = ap.HasValue(_license) && ap.Value(_license) is not null ? ap.Value(_license).ToString() : null
-//        },
-//        t => t.HasValue(_title) && t.Value(_title) is not null ? t.Value(_title).ToString() : null);
-//        foreach (var ap in grouped)
-//        {
-//            returnObjects.Add(new ReturnObject
-//            {
-//                Uri = ap.Key.Uri,
-//                Publisher = ap.Key.Publisher,
-//                Rights = ap.Key.Rights,
-//                License = ap.Key.License,
-//                Titles = ap.Select(t =>
-//                {
-//                    if (t is not null)
-//                    {
-//                        return t[..t.IndexOf('@')];
-//                    }
-//                    return t;
-//                }).ToList()
-//            });
-//        }
-//        return returnObjects;
-//    }
-//}
+using AutoMapper;
+using Coscine.ApiClient;
+using Coscine.ApiClient.Core.Api;
+using Coscine.ApiClient.Core.Client;
+using Coscine.ApiClient.Core.Model;
+using Coscine.KpiGenerator.Models;
+using Coscine.KpiGenerator.Models.ConfigurationModels;
+using Coscine.KpiGenerator.Utils;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using VDS.RDF;
+using VDS.RDF.Nodes;
+using VDS.RDF.Parsing;
+using static KPIGenerator.Utils.CommandLineOptions;
+
+namespace Coscine.KpiGenerator.Reportings.Resource;
+
+public class ApplicationProfileReporting
+{
+    private readonly IMapper _mapper;
+    private readonly KpiConfiguration _kpiConfiguration;
+
+    public static string AdminToken { get; set; } = null!;
+    public AdminApi AdminApi { get; init; }
+    public ProjectApi ProjectApi { get; init; }
+    public ApplicationProfileApi ApplicationProfileApi { get; }
+    public ApplicationProfileReportingOptions Options { get; private set; } = null!;
+    public string ReportingFileName { get; }
+
+    public ApplicationProfileReporting(IMapper mapper, IOptionsMonitor<KpiConfiguration> kpiConfiguration)
+    {
+        _mapper = mapper;
+        _kpiConfiguration = kpiConfiguration.CurrentValue;
+
+        ReportingFileName = _kpiConfiguration.ApplicationProfileKpi.FileName;
+
+        var configuration = new Configuration()
+        {
+            BasePath = "http://localhost:7206/coscine",
+            ApiKeyPrefix = { { "Authorization", "Bearer" } },
+            ApiKey = { { "Authorization", ApiConfigurationUtil.GenerateAdminToken(ApiConfigurationUtil.RetrieveJwtConfiguration()) } },
+        };
+
+        AdminApi = new AdminApi(configuration);
+        ProjectApi = new ProjectApi(configuration);
+        ApplicationProfileApi = new ApplicationProfileApi(configuration);
+    }
+
+    public async Task<bool> RunAsync(ApplicationProfileReportingOptions reportingOptions)
+    {
+        Options = reportingOptions;
+        var reportingFiles = await GenerateReportingAsync();
+        return await GitLabUtils.PublishAsync(reportingFiles);
+    }
+
+    public async Task<IEnumerable<ReportingFileObject>> GenerateReportingAsync()
+    {
+        var reportingFiles = new List<ReportingFileObject>();
+        var returnObjects = new List<ApplicationProfileReport>();
+
+        var applicationProfiles = await RequestUtil.WrapPagedRequest<ApplicationProfileDtoPagedResponse, ApplicationProfileDto>((pageNumber) => ApplicationProfileApi.GetApplicationProfilesAsync(pageNumber: pageNumber, pageSize: 500));
+        foreach(var ap in applicationProfiles)
+        {
+            var applicationProfile = await ApplicationProfileApi.GetApplicationProfileAsync(ap.Uri, RdfFormat.TextTurtle);
+
+            var g = new Graph();
+            StringParser.Parse(g, applicationProfile.Data.Definition.Content);
+
+            var titleUri = new Uri("http://purl.org/dc/terms/title");
+            var titles = g.GetTriplesWithPredicate(g.CreateUriNode(titleUri))
+                            .Select(triple => triple.Object.AsValuedNode().AsString())
+                            .ToList();
+
+            var publisherUri = new Uri("http://purl.org/dc/terms/publisher");
+            var publisher = g.GetTriplesWithPredicate(g.CreateUriNode(publisherUri))
+                            .FirstOrDefault()?.Object.AsValuedNode().AsString();
+
+            var rightsUri = new Uri("http://purl.org/dc/terms/rights");
+            var rights = g.GetTriplesWithPredicate(g.CreateUriNode(rightsUri))
+                            .FirstOrDefault()?.Object.AsValuedNode().AsString();
+
+            var licenseUri = new Uri("http://purl.org/dc/terms/license");
+            var license = g.GetTriplesWithPredicate(g.CreateUriNode(licenseUri))
+                            .FirstOrDefault()?.Object.AsValuedNode().AsString();
+
+            returnObjects.Add(new ApplicationProfileReport
+            {
+                Uri = ap.Uri,
+                Titles = titles ?? new List<string>(),
+                Publisher = publisher,
+                Rights = rights,
+                License = license
+            });
+        }
+
+        // General File
+        reportingFiles.Add(new ReportingFileObject
+        {
+            Path = Helpers.GetReportingPathGeneral(ReportingFileName),
+            Content = Helpers.ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjects, Formatting.Indented))
+        });
+
+        // No per organization file
+
+        return reportingFiles;
+    }
+}
\ No newline at end of file
diff --git a/src/KPI Generator/Reportings/Project/ProjectReporting.cs b/src/KPI Generator/Reportings/Project/ProjectReporting.cs
index 83ff3d75bf8dffe7fe80073a8c65e569646230f6..a826fe0c2c59ee2eb078e0a9523a3d9fff41bed7 100644
--- a/src/KPI Generator/Reportings/Project/ProjectReporting.cs	
+++ b/src/KPI Generator/Reportings/Project/ProjectReporting.cs	
@@ -4,7 +4,9 @@ using Coscine.ApiClient.Core.Api;
 using Coscine.ApiClient.Core.Client;
 using Coscine.ApiClient.Core.Model;
 using Coscine.KpiGenerator.Models;
+using Coscine.KpiGenerator.Models.ConfigurationModels;
 using Coscine.KpiGenerator.Utils;
+using Microsoft.Extensions.Options;
 using Newtonsoft.Json;
 using static KPIGenerator.Utils.CommandLineOptions;
 
@@ -13,6 +15,7 @@ namespace Coscine.KpiGenerator.Reportings.Project;
 public class ProjectReporting
 {
     private readonly IMapper _mapper;
+    private readonly KpiConfiguration _kpiConfiguration;
 
     public static string AdminToken { get; set; } = null!;
     public AdminApi AdminApi { get; init; }
@@ -20,17 +23,17 @@ public class ProjectReporting
     public ProjectReportingOptions Options { get; private set; } = null!;
     public string ReportingFileName { get; }
 
-    public ProjectReporting(IMapper mapper)
+    public ProjectReporting(IMapper mapper, IOptionsMonitor<KpiConfiguration> kpiConfiguration)
     {
         _mapper = mapper;
-        
-        ReportingFileName = "projects.json";
+        _kpiConfiguration = kpiConfiguration.CurrentValue;
+        ReportingFileName = _kpiConfiguration.ProjectKpi.FileName;
 
         var configuration = new Configuration()
         {
             BasePath = "http://localhost:7206/coscine",
             ApiKeyPrefix = { { "Authorization", "Bearer" } },
-            ApiKey = { { "Authorization", JwtUtil.GenerateAdminToken(JwtUtil.RetrieveJwtConfiguration()) } },
+            ApiKey = { { "Authorization", ApiConfigurationUtil.GenerateAdminToken(ApiConfigurationUtil.RetrieveJwtConfiguration()) } },
         };
 
         AdminApi = new AdminApi(configuration);
diff --git a/src/KPI Generator/Reportings/Resource/ResourceReporting.cs b/src/KPI Generator/Reportings/Resource/ResourceReporting.cs
index 79be9c2452c622cb9059e368ffee8bbf4b04dc77..d16519b11ebe97dd1a008021bfea361eb032a14d 100644
--- a/src/KPI Generator/Reportings/Resource/ResourceReporting.cs	
+++ b/src/KPI Generator/Reportings/Resource/ResourceReporting.cs	
@@ -4,7 +4,9 @@ using Coscine.ApiClient.Core.Api;
 using Coscine.ApiClient.Core.Client;
 using Coscine.ApiClient.Core.Model;
 using Coscine.KpiGenerator.Models;
+using Coscine.KpiGenerator.Models.ConfigurationModels;
 using Coscine.KpiGenerator.Utils;
+using Microsoft.Extensions.Options;
 using Newtonsoft.Json;
 using static KPIGenerator.Utils.CommandLineOptions;
 
@@ -13,6 +15,7 @@ namespace Coscine.KpiGenerator.Reportings.Resource;
 public class ResourceReporting
 {
     private readonly IMapper _mapper;
+    private readonly KpiConfiguration _kpiConfiguration;
 
     public static string AdminToken { get; set; } = null!;
     public AdminApi AdminApi { get; init; }
@@ -21,17 +24,17 @@ public class ResourceReporting
     public ResourceReportingOptions Options { get; private set; } = null!;
     public string ReportingFileName { get; }
 
-    public ResourceReporting(IMapper mapper)
+    public ResourceReporting(IMapper mapper, IOptionsMonitor<KpiConfiguration> kpiConfiguration)
     {
         _mapper = mapper;
-
-        ReportingFileName = "resources.json";
+        _kpiConfiguration = kpiConfiguration.CurrentValue;
+        ReportingFileName = _kpiConfiguration.ResourceKpi.FileName;
 
         var configuration = new Configuration()
         {
             BasePath = "http://localhost:7206/coscine",
             ApiKeyPrefix = { { "Authorization", "Bearer" } },
-            ApiKey = { { "Authorization", JwtUtil.GenerateAdminToken(JwtUtil.RetrieveJwtConfiguration()) } },
+            ApiKey = { { "Authorization", ApiConfigurationUtil.GenerateAdminToken(ApiConfigurationUtil.RetrieveJwtConfiguration()) } },
         };
 
         AdminApi = new AdminApi(configuration);
diff --git a/src/KPI Generator/Reportings/System/MaintenanceReturnObject.cs b/src/KPI Generator/Reportings/System/MaintenanceReturnObject.cs
deleted file mode 100644
index 7af2780672e51fd3ff6d8107a8c763a3f9cf1f6a..0000000000000000000000000000000000000000
--- a/src/KPI Generator/Reportings/System/MaintenanceReturnObject.cs	
+++ /dev/null
@@ -1,22 +0,0 @@
-using Newtonsoft.Json;
-
-namespace Coscine.KpiGenerator.Reportings.System;
-
-public class MaintenanceBannerObject
-{
-    [JsonProperty("id")]
-    public int Id { get; set; }
-    [JsonProperty("title")]
-    public string Title { get; set; } = null!;
-    [JsonProperty("short_message")]
-    public string ShortMessage { get; set; } = null!;
-    [JsonProperty("message")]
-    public string Message { get; set; } = null!;
-    [JsonProperty("status")]
-    public string Status { get; set; } = null!;
-    [JsonProperty("start_at")]
-    public DateTime? StartAt { get; set; } = null!;
-    [JsonProperty("end_at")]
-    public DateTime? EndAt { get; set; } = null!;
-}
-
diff --git a/src/KPI Generator/Reportings/System/ReturnObject.cs b/src/KPI Generator/Reportings/System/ReturnObject.cs
deleted file mode 100644
index 01b737e2134eadb760526ffcfff1975af61c805f..0000000000000000000000000000000000000000
--- a/src/KPI Generator/Reportings/System/ReturnObject.cs	
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Coscine.KpiGenerator.Reportings.System;
-
-/// <summary>
-/// Object containing the JSON structure for the reporting
-/// </summary>
-public class ReturnObject
-{
-    public List<MaintenanceBannerObject>? Banners { get; set; } = new();
-}
\ No newline at end of file
diff --git a/src/KPI Generator/Reportings/System/SystemReporting.cs b/src/KPI Generator/Reportings/System/SystemReporting.cs
index f6dfe4f74de1b2fb2854baecb9d2f691dc0cfff8..f71d3c7570ed334658896fcc199c9dbb136f525a 100644
--- a/src/KPI Generator/Reportings/System/SystemReporting.cs	
+++ b/src/KPI Generator/Reportings/System/SystemReporting.cs	
@@ -1,77 +1,95 @@
-//using Coscine.Configuration;
-//using Coscine.KpiGenerator.Utils;
-//using Microsoft.Extensions.Logging;
-//using Newtonsoft.Json;
-//using NLog.Extensions.Logging;
-//using System.Net.Http.Headers;
-//using System.Text;
-//using static KPIGenerator.Utils.CommandLineOptions;
+using AutoMapper;
+using Coscine.ApiClient;
+using Coscine.ApiClient.Core.Api;
+using Coscine.ApiClient.Core.Client;
+using Coscine.KpiGenerator.Models;
+using Coscine.KpiGenerator.Models.ConfigurationModels;
+using Coscine.KpiGenerator.Utils;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using System.Net.Http.Headers;
+using System.Text;
+using static KPIGenerator.Utils.CommandLineOptions;
 
-//namespace Coscine.KpiGenerator.Reportings.System;
+namespace Coscine.KpiGenerator.Reportings.Resource;
 
-//public class SystemReporting : Reporting<SystemReportingOptions>
-//{
-//    private readonly ILogger<SystemReporting> _logger;
+public class SystemReporting
+{
+    private readonly IMapper _mapper;
+    private readonly KpiConfiguration _kpiConfiguration;
+    private readonly HttpClient _httpClient;
 
-//    private readonly ConsulConfiguration _configuration;
+    public static string AdminToken { get; set; } = null!;
+    public AdminApi AdminApi { get; init; }
+    public ProjectApi ProjectApi { get; init; }
+    public SystemReportingOptions Options { get; private set; } = null!;
+    public string ReportingFileName { get; }
 
-//    public SystemReporting(SystemReportingOptions options) : base(options)
-//    {
-//        ReportingFileName = "system_status.json";
-//        _configuration = new ConsulConfiguration();
-//        _logger = LoggerFactory.Create(builder => builder.AddNLog()).CreateLogger<SystemReporting>();
-//    }
+    public SystemReporting(IMapper mapper, IHttpClientFactory httpClientFactory, IOptionsMonitor<KpiConfiguration> kpiConfiguration)
+    {
+        _mapper = mapper;
+        _kpiConfiguration = kpiConfiguration.CurrentValue;
+        _httpClient = httpClientFactory.CreateClient("MaintenanceClient");
 
-//    public override IEnumerable<ReportingFileObject> GenerateReportingAsync()
-//    {
-//        Console.WriteLine($" - {GetType().Name}: Begin reporting generation");
-//        _logger.LogInformation("{Name}: Begin reporting generation", GetType().Name);
-//        var reportingFiles = new List<ReportingFileObject>();
-//        var returnObject = GetSystemStatus();
+        ReportingFileName = _kpiConfiguration.SystemKpi.FileName;
 
-//        // General File
-//        reportingFiles.Add(new ReportingFileObject
-//        {
-//            Path = GetReportingPathGeneral(ReportingFileName),
-//            Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObject, Formatting.Indented))
-//        });
-//        Console.WriteLine($" - {GetType().Name}: \"{GetReportingPathGeneral(ReportingFileName)}\" generated successfully");
-//        _logger.LogInformation("{Name}: Generated successfully. {reportingFiles}", GetType().Name, reportingFiles);
+        var configuration = new Configuration()
+        {
+            BasePath = "http://localhost:7206/coscine",
+            ApiKeyPrefix = { { "Authorization", "Bearer" } },
+            ApiKey = { { "Authorization", ApiConfigurationUtil.GenerateAdminToken(ApiConfigurationUtil.RetrieveJwtConfiguration()) } },
+        };
 
-//        Console.WriteLine();
-//        return reportingFiles;
-//    }
+        AdminApi = new AdminApi(configuration);
+        ProjectApi = new ProjectApi(configuration);
+    }
 
-//    private ReturnObject GetSystemStatus()
-//    {
-//        return new ReturnObject()
-//        {
-//            Banners = GetMaintenanceBannersAsync().Result
-//            // Extend here with other specific props in the future
-//        };
-//    }
+    public async Task<bool> RunAsync(SystemReportingOptions reportingOptions)
+    {
+        Options = reportingOptions;
+        var reportingFiles = await GenerateReportingAsync();
+        return await GitLabUtils.PublishAsync(reportingFiles);
+    }
 
-//    private async Task<List<MaintenanceBannerObject>?> GetMaintenanceBannersAsync()
-//    {
-//        var httpClient = new HttpClient();
-//        var requestMessage = new HttpRequestMessage()
-//        {
-//            RequestUri = new Uri("https://noc-portal.rz.rwth-aachen.de/ticket/api/coscine/tickets"),
-//            Method = HttpMethod.Get
-//        };
+    public async Task<IEnumerable<ReportingFileObject>> GenerateReportingAsync()
+    {
+        var reportingFiles = new List<ReportingFileObject>();
+        var returnObject = new SystemReport()
+        {
+            Banners = await GetMaintenanceBannersAsync(),
+        };
 
-//        // Add Basic Authentication Headers
-//        var authenticationString = $"{_configuration.GetStringAndWait("coscine/global/maintenance/user")}:{_configuration.GetStringAndWait("coscine/global/maintenance/password")}";
-//        var base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.ASCII.GetBytes(authenticationString));
-//        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString);
+        // General File
+        reportingFiles.Add(new ReportingFileObject
+        {
+            Path = Helpers.GetReportingPathGeneral(ReportingFileName),
+            Content = Helpers.ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObject, Formatting.Indented)),
+        });
 
-//        var result = await httpClient.SendAsync(requestMessage);
-//        var responseBody = JsonConvert.DeserializeObject<List<MaintenanceBannerObject>>(result.Content.ReadAsStringAsync().Result);
-//        if (responseBody is null)
-//        {
-//            return null;
-//        }
-//        return responseBody.OrderBy(e => e.StartAt).ToList();
-//    }
-//}
+        // No per organization file
 
+        return reportingFiles;
+    }
+
+    private async Task<List<MaintenanceReport>?> GetMaintenanceBannersAsync()
+    {
+        var requestMessage = new HttpRequestMessage()
+        {
+            RequestUri = new Uri(_kpiConfiguration.SystemKpi.Maintenance.Url),
+            Method = System.Net.Http.HttpMethod.Get
+        };
+
+        // Add Basic Authentication Headers
+        var authenticationString = $"{_kpiConfiguration.SystemKpi.Maintenance.Username}:{_kpiConfiguration.SystemKpi.Maintenance.Password}";
+        var base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.ASCII.GetBytes(authenticationString));
+        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString);
+
+        var result = await _httpClient.SendAsync(requestMessage);
+        var responseBody = JsonConvert.DeserializeObject<List<MaintenanceReport>>(result.Content.ReadAsStringAsync().Result);
+        if (responseBody is null)
+        {
+            return null;
+        }
+        return responseBody.OrderBy(e => e.StartAt).ToList();
+    }
+}
\ No newline at end of file
diff --git a/src/KPI Generator/Reportings/User/ReturnObject.cs b/src/KPI Generator/Reportings/User/ReturnObject.cs
deleted file mode 100644
index ecca1f6cbe25f332d94897dc72746d2fc76222b1..0000000000000000000000000000000000000000
--- a/src/KPI Generator/Reportings/User/ReturnObject.cs	
+++ /dev/null
@@ -1,24 +0,0 @@
-//using Coscine.Database.ReturnObjects;
-//using Coscine.KpiGenerator.Utils;
-
-//namespace Coscine.KpiGenerator.Reportings.User;
-
-///// <summary>
-///// Object containing the JSON structure for the reporting
-///// </summary>
-//public class ReturnObject
-//{
-//    public List<RelatedProject> RelatedProjects { get; set; } = new();
-//    public List<Organization> Organizations { get; set; } = new();
-//    public List<Organization> Institutes { get; set; } = new();
-//    public List<DisciplineObject> Disciplines { get; set; } = new();
-//    public List<ExternalAuthenticatorsObject> LoginProviders { get; set; } = new();
-//    public DateTime? LatestActivity { get; set; } = null;
-
-
-//    public class RelatedProject
-//    {
-//        public Guid ProjectId { get; set; }
-//        public string Role { get; set; } = null!;
-//    }
-//}
diff --git a/src/KPI Generator/Reportings/User/UserReporting.cs b/src/KPI Generator/Reportings/User/UserReporting.cs
index 7814b9e45f73970271b733e28aa79c943c793883..be632d92ab87ecb2aca4b921de801479d2bbfe05 100644
--- a/src/KPI Generator/Reportings/User/UserReporting.cs	
+++ b/src/KPI Generator/Reportings/User/UserReporting.cs	
@@ -4,7 +4,9 @@ using Coscine.ApiClient.Core.Api;
 using Coscine.ApiClient.Core.Client;
 using Coscine.ApiClient.Core.Model;
 using Coscine.KpiGenerator.Models;
+using Coscine.KpiGenerator.Models.ConfigurationModels;
 using Coscine.KpiGenerator.Utils;
+using Microsoft.Extensions.Options;
 using Newtonsoft.Json;
 using static KPIGenerator.Utils.CommandLineOptions;
 
@@ -13,24 +15,26 @@ namespace Coscine.KpiGenerator.Reportings.Resource;
 public class UserReporting
 {
     private readonly IMapper _mapper;
+    private readonly KpiConfiguration _kpiConfiguration;
 
     public static string AdminToken { get; set; } = null!;
     public AdminApi AdminApi { get; init; }
     public ProjectApi ProjectApi { get; init; }
     public UserReportingOptions Options { get; private set; } = null!;
+    public KpiConfiguration KpiConfiguration { get; } = new();
     public string ReportingFileName { get; }
 
-    public UserReporting(IMapper mapper)
+    public UserReporting(IMapper mapper, IOptionsMonitor<KpiConfiguration> kpiConfiguration)
     {
         _mapper = mapper;
-
-        ReportingFileName = "users.json";
+        _kpiConfiguration = kpiConfiguration.CurrentValue;
+        ReportingFileName = _kpiConfiguration.UserKpi.FileName;
 
         var configuration = new Configuration()
         {
             BasePath = "http://localhost:7206/coscine",
             ApiKeyPrefix = { { "Authorization", "Bearer" } },
-            ApiKey = { { "Authorization", JwtUtil.GenerateAdminToken(JwtUtil.RetrieveJwtConfiguration()) } },
+            ApiKey = { { "Authorization", ApiConfigurationUtil.GenerateAdminToken(ApiConfigurationUtil.RetrieveJwtConfiguration()) } },
         };
 
         AdminApi = new AdminApi(configuration);
diff --git a/src/KPI Generator/Reportings/User/UserReporting2.cs b/src/KPI Generator/Reportings/User/UserReporting2.cs
deleted file mode 100644
index cc12b1961e299364d488eabd799cc1eba672046c..0000000000000000000000000000000000000000
--- a/src/KPI Generator/Reportings/User/UserReporting2.cs	
+++ /dev/null
@@ -1,260 +0,0 @@
-//using Coscine.Database.Models;
-//using Coscine.Database.ReturnObjects;
-//using Coscine.KpiGenerator.Utils;
-//using Coscine.Metadata;
-//using Microsoft.Extensions.Logging;
-//using Newtonsoft.Json;
-//using NLog.Extensions.Logging;
-//using VDS.RDF.Query;
-//using static KPIGenerator.Utils.CommandLineOptions;
-
-//namespace Coscine.KpiGenerator.Reportings.User;
-
-//public class UserReporting : Reporting<UserReportingOptions>
-//{
-//    private readonly ILogger<UserReporting> _logger;
-
-//    private readonly ExternalIdModel _externalIdModel;
-//    private readonly ProjectRoleModel _projectRoleModel;
-//    private readonly ProjectModel _projectModel;
-//    private readonly RoleModel _roleModel;
-//    private readonly UserModel _userModel;
-//    private readonly LogModel _logModel;
-
-//    public UserReporting(UserReportingOptions options) : base(options)
-//    {
-//        ReportingFileName = "users.json";
-//        _externalIdModel = new ExternalIdModel();
-//        _projectRoleModel = new ProjectRoleModel();
-//        _projectModel = new ProjectModel();
-//        _roleModel = new RoleModel();
-//        _userModel = new UserModel();
-//        _logModel = new LogModel();
-
-//        _logger = LoggerFactory.Create(builder => builder.AddNLog()).CreateLogger<UserReporting>();
-//    }
-
-//    public override IEnumerable<ReportingFileObject> GenerateReportingAsync()
-//    {
-//        Console.WriteLine($" - {GetType().Name}: Begin reporting generation");
-//        _logger.LogInformation("{Name}: Begin reporting generation", GetType().Name);
-//        var users = _userModel.GetAllWhere((user) => user.Tosaccepteds.Any());
-//        var reportingFiles = new List<ReportingFileObject>();
-//        var returnObjects = Generate(users);
-
-//        // General File
-//        reportingFiles.Add(new ReportingFileObject
-//        {
-//            Path = GetReportingPathGeneral(ReportingFileName),
-//            Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjects, Formatting.Indented))
-//        });
-//        Console.WriteLine($" - {GetType().Name}: \"{GetReportingPathGeneral(ReportingFileName)}\" generated successfully");
-//        _logger.LogInformation("{Name}: Generated successfully. {reportingFiles}", GetType().Name, reportingFiles);
-
-//        // Per Organization
-//        reportingFiles.AddRange(GeneratePerOrganization(returnObjects));
-
-//        Console.WriteLine();
-//        return reportingFiles;
-//    }
-
-//    private List<ReturnObject> Generate(IEnumerable<Database.DataModel.User> users)
-//    {
-//        var returnObjects = new List<ReturnObject>();
-//        foreach (var user in users)
-//        {
-//            var userReturnObject = _userModel.CreateReturnObjectFromDatabaseObject(user);
-//            var (organizations, institutes) = GetUserAffiliation(userReturnObject);
-//            var userReportEntry = new ReturnObject
-//            {
-//                RelatedProjects = GetRelatedProjects(user.Id),
-//                Organizations = organizations,
-//                Institutes = institutes,
-//                Disciplines = userReturnObject.Disciplines.ToList(),
-//                LoginProviders = userReturnObject.ExternalAuthenticators.ToList(),
-//                LatestActivity = GetLatestActivity(user.Id)
-//            };
-//            returnObjects.Add(userReportEntry);
-//        }
-//        return returnObjects;
-//    }
-
-//    private IEnumerable<ReportingFileObject> GeneratePerOrganization(List<ReturnObject> returnObjects)
-//    {
-//        var reportingFilesPerOrganization = new List<ReportingFileObject>();
-//        var organizationsFromUsers = GetTopLevelOrganizationsFromEntries(returnObjects.SelectMany(ro => ro.Organizations));
-//        foreach (var entry in organizationsFromUsers)
-//        {
-//            List<ReturnObject> returnObjectsForOrganization;
-
-//            // Handling of "Other" organization
-//            if (entry.RorUrl.Equals("https://ror.org/") || entry.RorUrl.Equals("http://ror.org/"))
-//            {
-//                returnObjectsForOrganization = returnObjects.Where(ro => ro.Organizations.Select(o => o.RorUrl).Any(e => e.Equals("https://ror.org/") || e.Equals("http://ror.org/"))).ToList();
-//                entry.RorUrl = _otherOrganization.RorUrl;
-//            }
-//            else
-//            {
-//                returnObjectsForOrganization = returnObjects.Where(ro => ro.Organizations.Select(o => o.RorUrl).Any(e => e.Contains(entry.RorUrl))).ToList();
-//            }
-
-//            var reportingFile = new ReportingFileObject
-//            {
-//                Path = GetReportingPathOrganization(entry.RorUrl, ReportingFileName),
-//                Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjectsForOrganization, Formatting.Indented))
-//            };
-
-//            reportingFilesPerOrganization.Add(reportingFile);
-
-//            Console.WriteLine($" - {GetType().Name}: \"{GetReportingPathOrganization(entry.RorUrl, ReportingFileName)}\" generated successfully");
-//            _logger.LogInformation("{Name}: Generated successfully {ReportingFile}.", GetType().Name, reportingFile);
-//        }
-//        return reportingFilesPerOrganization;
-//    }
-
-//    private List<ReturnObject.RelatedProject> GetRelatedProjects(Guid id)
-//    {
-//        var result = new List<ReturnObject.RelatedProject>();
-//        var projectRoles = _projectRoleModel.GetAllWhere(role => role.UserId.Equals(id));
-//        if (projectRoles.Any())
-//        {
-//            foreach (var projectRole in projectRoles)
-//            {
-//                if (_projectModel.GetById(projectRole.ProjectId) is not null) // null if project has been deleted
-//                {
-//                    result.Add(new ReturnObject.RelatedProject
-//                    {
-//                        ProjectId = projectRole.ProjectId,
-//                        Role = _roleModel.GetById(projectRole.RoleId).DisplayName
-//                    });
-//                }
-//            }
-//        }
-//        return result;
-//    }
-
-//    private (List<Organization> organizations, List<Organization> institutes) GetUserAffiliation(UserObject user)
-//    {
-//        var affiliations = new List<Organization>();
-
-//        // Bellow code taken from Organizations API
-//        var externalIds = _externalIdModel.GetAllWhere((externalId) => externalId.UserId == user.Id);
-//        var externalIdList = new List<string>();
-//        foreach (var externalId in externalIds)
-//        {
-//            externalIdList.Add(externalId.ExternalId1);
-//        }
-//        var externalOrganizations = externalIds.Select((externalId) => externalId.Organization);
-
-//        var triples = Helpers.WrapRequest(() => RdfStoreConnector.GetTriples(null, null, null, 1, externalIdList).ToList());
-//        foreach (var externalOrganization in externalOrganizations)
-//        {
-//            triples.AddRange(Helpers.WrapRequest(() => RdfStoreConnector.GetOrganizationByEntityId(externalOrganization)));
-//        }
-//        triples = triples.Distinct().ToList();
-
-//        foreach (var triple in triples)
-//        {
-//            affiliations.Add(new()
-//            {
-//                Name = triple.Object.ToString(),
-//                RorUrl = triple.Subject.ToString()
-//            });
-//        }
-
-//        // Clean up
-//        affiliations = CleanUpOther(affiliations);
-
-//        // Split affiliations to "organizations" and "institutes"
-//        var organizations = affiliations.Where(a => !a.RorUrl.Contains('#')).ToList();
-//        var institutes = affiliations.Where(a => a.RorUrl.Contains('#')).ToList();
-
-//        // Find the RoR of the organization based on its "rdfs:label".
-//        var orgFromSqlDb = TryGetOrganizationByLabel(user.Organization);
-//        if (orgFromSqlDb is not null)
-//            organizations.Add(orgFromSqlDb);
-
-//        // Find the RoR of the institute based on its "rdfs:label".
-//        var instFromSqlDb = TryGetOrganizationByLabel(user.Institute);
-//        if (instFromSqlDb is not null)
-//            institutes.Add(instFromSqlDb);
-
-//        return (
-//            organizations.DistinctBy(o => o.RorUrl).ToList(),
-//            institutes.DistinctBy(i => i.RorUrl).ToList()
-//        );
-//    }
-
-//    private Organization? TryGetOrganizationByLabel(string rdfsLabel)
-//    {
-//        if (string.IsNullOrWhiteSpace(rdfsLabel))
-//        {
-//            return null;
-//        }
-//        var _queryString = new SparqlParameterizedString()
-//        {
-//            CommandText = $@"
-//                PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
-
-//                SELECT DISTINCT ?ror
-//                WHERE {{
-//                    VALUES ?name
-//                    {{
-//                        '{rdfsLabel}'
-//                    }} .
-//                    ?ror rdfs:label ?name .
-//                    FILTER( CONTAINS( STR(?ror), 'ror.org' ) )
-//                }}
-//            "
-//        };
-//        using var results = Helpers.WrapRequest(() => RdfStoreConnector.QueryEndpoint.QueryWithResultSet(_queryString.ToString()));
-//        if (!results.IsEmpty)
-//        {
-//            var ror = results.Select(x => x.Value("ror").ToString());   // Get the value for ?ror
-//            if (ror.Any())
-//            {
-//                return FetchOrganizationByRor(ror.ToList()[0]);
-//            }
-//        }
-//        return null;
-//    }
-
-//    private DateTime? GetLatestActivity(Guid id)
-//    {
-//        var today = DateTime.Today;
-//        var latestLog = _logModel
-//            .GetAllWhere(l =>
-//                l.LogLevel.Equals("Analytics")
-//                && l.UserId.Equals(id)
-//                && l.ServerTimestamp < today)
-//            .OrderByDescending(a => a.ServerTimestamp)
-//            .FirstOrDefault();
-//        if (latestLog is not null)
-//        {
-//            return latestLog.ServerTimestamp;
-//        }
-//        else return null;
-//    }
-
-//    private List<Organization> CleanUpOther(List<Organization> affiliations)
-//    {
-//        // Special case until `https://ror.org/%20https://ror.org/` is moved to `https://ror.org/_other`
-//        if (affiliations.Any(o => o.RorUrl.Equals("https://ror.org/%20https://ror.org/") || o.RorUrl.Equals("https://ror.org/") || o.RorUrl.Equals("http://ror.org/")))
-//        {
-//            var cleanedUpAffiliations = affiliations;
-//            foreach (var entry in cleanedUpAffiliations)
-//            {
-//                if (entry.RorUrl.Equals("https://ror.org/%20https://ror.org/") || entry.RorUrl.Equals("https://ror.org/") || entry.RorUrl.Equals("http://ror.org/"))
-//                {
-//                    cleanedUpAffiliations[cleanedUpAffiliations.IndexOf(entry)] = new()
-//                    {
-//                        Name = _otherOrganization.Name,
-//                        RorUrl = _otherOrganization.RorUrl
-//                    };
-//                }
-//            }
-//            return cleanedUpAffiliations;
-//        }
-//        return affiliations;
-//    }
-//}
\ No newline at end of file