// post task
        private async Task <ActionResult> PostTask(Grunt egressGrunt, Grunt targetGrunt, ModelUtilities.GruntEncryptedMessage outputMessage, string guid)
        {
            if (targetGrunt == null || targetGrunt.Status != GruntStatus.Active || egressGrunt == null || egressGrunt.Guid != guid)
            {
                // Invalid GUID. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            string TaskName = outputMessage.Meta;

            if (string.IsNullOrWhiteSpace(TaskName))
            {
                // Invalid task response. This happens on post-register write
                return(NotFound());
            }
            GruntTasking gruntTasking;

            try
            {
                gruntTasking = await _client.ApiGruntsTaskingsByTaskingnameGetAsync(TaskName);
            }
            catch (HttpOperationException)
            {
                // Invalid taskname. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            if (targetGrunt == null || targetGrunt.Status != GruntStatus.Active)
            {
                // Invalid Grunt. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }
            if (!outputMessage.VerifyHMAC(Convert.FromBase64String(targetGrunt.GruntNegotiatedSessionKey)))
            {
                // Invalid signature. Almost certainly not a legitimate Grunt request, respond NotFound
                return(NotFound());
            }
            string taskOutput = Common.CovenantEncoding.GetString(_utilities.GruntSessionDecrypt(targetGrunt, outputMessage));

            gruntTasking.GruntCommand.CommandOutput = new CommandOutput
            {
                Id             = 0,
                GruntCommandId = gruntTasking.GruntCommandId,
                Output         = taskOutput
            };
            gruntTasking.GruntCommand.CommandOutputId = 0;
            gruntTasking.Status         = GruntTaskingStatus.Completed;
            gruntTasking.CompletionTime = DateTime.UtcNow;
            gruntTasking.GruntCommand   = await _client.ApiCommandsPutAsync(gruntTasking.GruntCommand);

            await _client.ApiTaskingsPutAsync(gruntTasking);

            targetGrunt.LastCheckIn = DateTime.UtcNow;
            await _client.ApiGruntsPutAsync(targetGrunt);

            return(Ok());
        }